# __ __ __ # \ \ / / / / # \ V / / / # \_/ \/ # # V E C T O R # Configuration # # ------------------------------------------------------------------------------ # Website: https://vector.dev # Docs: https://vector.dev/docs # Chat: https://chat.vector.dev # ------------------------------------------------------------------------------ # Solana log source [sources.solana_logs] type = "file" read_from = "beginning" ignore_older_secs = 60 include = ["/home/sol/solana-rpc.log"] # Parse Solana logs [transforms.parse_solana_logs] type = "remap" drop_on_error = true inputs = ["solana_logs"] source = ''' .grok_results = parse_groks!( .message, patterns: [ "\\[%{_timestamp} %{_loglevel} %{_source}\\] %{_message}" ], aliases: { "_timestamp": "%{TIMESTAMP_ISO8601:timestamp}", "_loglevel": "%{LOGLEVEL:level}", "_message": "%{GREEDYDATA:message}", "_source": "%{DATA:source}" } ) .dt = .grok_results.timestamp .level = .grok_results.level .source = strip_whitespace!(.grok_results.source) .message = .grok_results.message del(.grok_results) ''' # Filter Solana logs for Clockwork logs [transforms.filter_solana_logs] inputs = ["parse_solana_logs"] type = "filter" condition = ''' .source == "clockwork_plugin::builders::thread_exec" || .source == "clockwork_plugin::executors::tx" || .source == "solana_validator" || .source == "solana_core::validator" ''' # Parse program logs into JSON [transforms.parse_clockwork_logs] type = "remap" inputs = ["filter_solana_logs"] source = ''' if .source == "clockwork_plugin::builders::thread_exec" { .grok_results = parse_groks!( .message, patterns: ["thread: %{_thread} simulation_error: %{_error} logs: %{_logs}"], aliases: { "_thread": "%{DATA:thread}", "_error": "%{QUOTEDSTRING:error}", "_logs": "%{GREEDYDATA:logs}" } ) .thread = .grok_results.thread .error_msg = .grok_results.error .program_logs = parse_json!(.grok_results.logs) del(.grok_results) } ''' # Filter for only Clockwork simulation logs [transforms.filter_clockwork_simulation_logs] type = "filter" inputs = ["parse_clockwork_logs"] condition = ''' .source == "clockwork_plugin::builders::thread_exec" && !is_null(.error_msg) ''' # Throttle Clockwork simulation logs [transforms.throttle_clockwork_simulation_logs] type = "throttle" inputs = ["filter_clockwork_simulation_logs"] key_field = "{{ thread }}" threshold = 1 window_secs = 30 # Pipe to Logtail [sinks.logtail] type = "http" uri = "https://in.logtail.com/" encoding.codec = "json" auth.strategy = "bearer" auth.token = "YOUR_AUTH_KEY" inputs = ["throttle_clockwork_simulation_logs"] # Test Solana log parser [[tests]] name = "solana_metrics_test" [[tests.inputs]] insert_at = "parse_solana_logs" type = "raw" value = "[2023-01-10T17:21:42.218012551Z INFO solana_metrics::metrics] datapoint: pubsub_notifications created_to_queue_time_us=20i" [[tests.outputs]] extract_from = "parse_solana_logs" [[tests.outputs.conditions]] type = "vrl" source = ''' assert_eq!(.dt, "2023-01-10T17:21:42.218012551Z") assert_eq!(.level, "INFO") assert_eq!(.source, "solana_metrics::metrics") assert_eq!(.message, "datapoint: pubsub_notifications created_to_queue_time_us=20i") ''' # Test Clockwork log parser [[tests]] name = "clockwork_simulation_test" [[tests.inputs]] insert_at = "parse_solana_logs" type = "raw" value = '[2023-01-11T04:37:09.059509973Z INFO clockwork_plugin::builders::thread_exec] thread: 9K4g3LYdwKhTJVQv85EvsAn7uHo5pSyq7qNs2FqrsD1K simulation_error: "Transaction results in an account (1) without insufficient funds for rent" logs: ["Program ComputeBudget111111111111111111111111111111 invoke [1]", "Program ComputeBudget111111111111111111111111111111 success", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv invoke [1]", "Program log: Instruction: ThreadKickoff", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv consumed 83495 of 1400000 compute units", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv success"]' [[tests.outputs]] extract_from = "parse_clockwork_logs" [[tests.outputs.conditions]] type = "vrl" source = ''' assert_eq!(.dt, "2023-01-11T04:37:09.059509973Z") assert_eq!(.level, "INFO") assert_eq!(.source, "clockwork_plugin::builders::thread_exec") assert_eq!(.thread, "9K4g3LYdwKhTJVQv85EvsAn7uHo5pSyq7qNs2FqrsD1K") assert_eq!(.error_msg, "\"Transaction results in an account (1) without insufficient funds for rent\"") assert_eq!(.program_logs, ["Program ComputeBudget111111111111111111111111111111 invoke [1]", "Program ComputeBudget111111111111111111111111111111 success", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv invoke [1]", "Program log: Instruction: ThreadKickoff", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv consumed 83495 of 1400000 compute units", "Program 3XXuUFfweXBwFgFfYaejLvZE4cGZiHgKiGfMtdxNzYmv success"]) '''