├── .github ├── ISSUE_TEMPLATE │ ├── bug-report---.md │ ├── config.yml │ ├── enhancement-request---.md │ └── troubleshooting.md ├── PULL_REQUEST_TEMPLATE.md ├── auto_assign.yml ├── dependabot.yml └── workflows │ ├── autoassign.yml │ ├── ci.yaml │ └── repolinter.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── GETTING_STARTED.md ├── GUIDE.md ├── LICENSE.txt ├── MIGRATION.md ├── README.md ├── THIRD_PARTY_NOTICES.md ├── codecov.yml ├── run-tests.sh └── v3 ├── LICENSE.txt ├── examples ├── client │ └── main.go ├── custom-instrumentation │ └── main.go ├── oom │ └── main.go ├── server-http │ └── main.go ├── server │ ├── Dockerfile │ └── main.go └── short-lived-process │ └── main.go ├── go.mod ├── integrations ├── logcontext-v2 │ ├── logWriter │ │ ├── LICENSE.txt │ │ ├── Readme.md │ │ ├── example │ │ │ └── main.go │ │ ├── go.mod │ │ ├── log-writer.go │ │ └── log-writer_test.go │ ├── nrlogrus │ │ ├── LICENSE.txt │ │ ├── example │ │ │ └── main.go │ │ ├── formatter.go │ │ ├── formatter_test.go │ │ └── go.mod │ ├── nrslog │ │ ├── LICENSE.txt │ │ ├── attributes.go │ │ ├── config.go │ │ ├── example │ │ │ └── main.go │ │ ├── go.mod │ │ ├── handler.go │ │ ├── handler_test.go │ │ ├── linking.go │ │ ├── linking_test.go │ │ └── wrap.go │ ├── nrwriter │ │ ├── LICENSE.txt │ │ ├── go.mod │ │ ├── nrwriter.go │ │ └── nrwriter_test.go │ ├── nrzap │ │ ├── LICENSE.txt │ │ ├── example │ │ │ └── main.go │ │ ├── go.mod │ │ ├── nrzap.go │ │ └── nrzap_test.go │ ├── nrzerolog │ │ ├── LICENSE.txt │ │ ├── Readme.md │ │ ├── example │ │ │ └── main.go │ │ ├── go.mod │ │ ├── hook.go │ │ └── hook_test.go │ └── zerologWriter │ │ ├── LICENSE.txt │ │ ├── Readme.md │ │ ├── example │ │ └── main.go │ │ ├── go.mod │ │ ├── zerolog-writer.go │ │ └── zerolog-writer_test.go ├── logcontext │ ├── README.md │ ├── logcontext.go │ └── nrlogrusplugin │ │ ├── LICENSE.txt │ │ ├── README.md │ │ ├── example │ │ └── main.go │ │ ├── go.mod │ │ ├── nrlogrusplugin.go │ │ └── nrlogrusplugin_test.go ├── nramqp │ ├── LICENSE.txt │ ├── examples │ │ ├── consumer │ │ │ └── main.go │ │ └── publisher │ │ │ └── main.go │ ├── go.mod │ ├── headers.go │ ├── headers_test.go │ ├── nramqp.go │ └── nramqp_test.go ├── nrawsbedrock │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ └── nrawsbedrock.go ├── nrawssdk-v1 │ ├── LICENSE.txt │ ├── README.md │ ├── go.mod │ ├── nrawssdk.go │ └── nrawssdk_test.go ├── nrawssdk-v2 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrawssdk.go │ └── nrawssdk_test.go ├── nrb3 │ ├── LICENSE.txt │ ├── README.md │ ├── example_test.go │ ├── go.mod │ ├── nrb3.go │ ├── nrb3_doc.go │ └── nrb3_test.go ├── nrecho-v3 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrecho.go │ └── nrecho_test.go ├── nrecho-v4 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrecho.go │ └── nrecho_test.go ├── nrelasticsearch-v7 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── example_test.go │ ├── go.mod │ ├── internal │ │ └── http-endpoint-list-utility │ │ │ ├── endpoints.txt │ │ │ └── main.go │ ├── nrelastic.go │ └── nrelastic_test.go ├── nrfasthttp │ ├── LICENSE.txt │ ├── examples │ │ ├── client-fasthttp │ │ │ ├── go.mod │ │ │ └── main.go │ │ └── server-fasthttp │ │ │ ├── go.mod │ │ │ └── main.go │ ├── go.mod │ ├── instrumentation.go │ ├── instrumentation_test.go │ ├── segment.go │ └── segment_test.go ├── nrfiber │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── main.go │ │ └── main_test.go │ ├── go.mod │ ├── nfiber_test.go │ ├── nrfiber.go │ └── nrfiber_context_test.go ├── nrgin │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrgin.go │ ├── nrgin_context_test.go │ └── nrgin_test.go ├── nrgochi │ ├── LICENSE.txt │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrgochi.go │ └── nrgochi_test.go ├── nrgorilla │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── example_test.go │ ├── go.mod │ ├── nrgorilla.go │ └── nrgorilla_test.go ├── nrgraphgophers │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrgraphgophers.go │ ├── nrgraphgophers_example_test.go │ └── nrgraphgophers_test.go ├── nrgraphqlgo │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── LICENSE.txt │ │ ├── go.mod │ │ └── main.go │ ├── go.mod │ ├── nrgraphqlgo.go │ └── nrgraphqlgo_test.go ├── nrgrpc │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── client │ │ │ └── client.go │ │ ├── sampleapp │ │ │ ├── sampleapp.pb.go │ │ │ └── sampleapp.proto │ │ └── server │ │ │ └── server.go │ ├── go.mod │ ├── nrgrpc_client.go │ ├── nrgrpc_client_test.go │ ├── nrgrpc_doc.go │ ├── nrgrpc_server.go │ ├── nrgrpc_server_test.go │ └── testapp │ │ ├── README.md │ │ ├── server.go │ │ ├── testapp.pb.go │ │ └── testapp.proto ├── nrhttprouter │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrhttprouter.go │ └── nrhttprouter_test.go ├── nrlambda │ ├── LICENSE.txt │ ├── README.md │ ├── config.go │ ├── config_test.go │ ├── events.go │ ├── events_test.go │ ├── example │ │ └── main.go │ ├── go.mod │ ├── handler.go │ └── handler_test.go ├── nrlogrus │ ├── LICENSE.txt │ ├── README.md │ ├── examples │ │ ├── server-http-logs-in-context │ │ │ └── main.go │ │ └── server │ │ │ └── main.go │ ├── go.mod │ ├── nrlogrus.go │ └── nrlogrus_test.go ├── nrlogxi │ ├── LICENSE.txt │ ├── README.md │ ├── example_test.go │ ├── go.mod │ ├── nrlogxi.go │ └── nrlogxi_test.go ├── nrmicro │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── README.md │ │ ├── client │ │ │ └── client.go │ │ ├── proto │ │ │ ├── greeter.micro.go │ │ │ ├── greeter.pb.go │ │ │ └── greeter.proto │ │ ├── pubsub │ │ │ └── main.go │ │ └── server │ │ │ └── server.go │ ├── go.mod │ ├── nrmicro.go │ ├── nrmicro_doc.go │ └── nrmicro_test.go ├── nrmongo │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrmongo.go │ └── nrmongo_test.go ├── nrmssql │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrmssql.go │ └── nrmssql_test.go ├── nrmysql │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrmysql.go │ └── nrmysql_test.go ├── nrnats │ ├── LICENSE.txt │ ├── README.md │ ├── example_test.go │ ├── examples │ │ ├── README.md │ │ └── main.go │ ├── go.mod │ ├── nrnats.go │ ├── nrnats_doc.go │ ├── nrnats_test.go │ └── test │ │ ├── LICENSE.txt │ │ └── go.mod ├── nropenai │ ├── LICENSE.txt │ ├── examples │ │ ├── chatcompletion │ │ │ └── chatcompletion_example.go │ │ ├── chatcompletionfeedback │ │ │ └── chatcompletionfeedback.go │ │ ├── chatcompletionstreaming │ │ │ └── chatcompletionstreaming.go │ │ └── embeddings │ │ │ └── embeddings_example.go │ ├── go.mod │ ├── nropenai.go │ └── nropenai_test.go ├── nrpgx │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── sql_compat │ │ │ └── main.go │ │ └── sqlx │ │ │ ├── LICENSE.txt │ │ │ ├── go.mod │ │ │ └── main.go │ ├── go.mod │ ├── nrpgx.go │ └── nrpgx_test.go ├── nrpgx5 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── LICENSE.txt │ │ ├── pgx │ │ │ ├── LICENSE.txt │ │ │ └── main.go │ │ └── pgxpool │ │ │ ├── LICENSE.txt │ │ │ └── main.go │ ├── go.mod │ ├── nrpgx5.go │ ├── nrpgx5_test.go │ ├── pgsnap_tracer_batch.txt │ ├── pgsnap_tracer_connect.txt │ ├── pgsnap_tracer_inpool.txt │ └── pgsnap_tracer_trace_crud.txt ├── nrpkgerrors │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── example_test.go │ ├── go.mod │ ├── nrkpgerrors_test.go │ └── nrpkgerrors.go ├── nrpq │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ ├── main.go │ │ └── sqlx │ │ │ ├── LICENSE.txt │ │ │ ├── go.mod │ │ │ └── main.go │ ├── go.mod │ ├── nrpq.go │ └── nrpq_test.go ├── nrredis-v7 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrredis.go │ ├── nrredis_example_test.go │ └── nrredis_test.go ├── nrredis-v8 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrredis.go │ ├── nrredis_example_test.go │ └── nrredis_test.go ├── nrredis-v9 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrredis.go │ ├── nrredis_db_test.go │ ├── nrredis_example_test.go │ ├── nrredis_test.go │ └── util │ │ └── empty_db.go ├── nrsarama │ ├── LICENSE.txt │ ├── consumer.go │ ├── example │ │ ├── consumer │ │ │ └── consumerexample.go │ │ └── producer │ │ │ └── producerexample.go │ ├── go.mod │ ├── nrsarama_test.go │ └── producer.go ├── nrsecureagent │ └── README.md ├── nrsecurityagent │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── example.go │ ├── go.mod │ └── nrsecurityagent.go ├── nrslog │ ├── LICENSE.txt │ ├── README.md │ ├── example_test.go │ ├── go.mod │ └── nrslog.go ├── nrsnowflake │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrsnowflake.go │ └── nrsnowflake_test.go ├── nrsqlite3 │ ├── LICENSE.txt │ ├── README.md │ ├── example │ │ └── main.go │ ├── go.mod │ ├── nrsqlite3.go │ └── nrsqlite3_test.go ├── nrstan │ ├── LICENSE.txt │ ├── README.md │ ├── examples │ │ ├── LICENSE.txt │ │ ├── README.md │ │ ├── go.mod │ │ └── main.go │ ├── go.mod │ ├── nrstan.go │ ├── nrstan_doc.go │ └── test │ │ ├── LICENSE.txt │ │ ├── go.mod │ │ └── nrstan_test.go ├── nrzap │ ├── LICENSE.txt │ ├── README.md │ ├── example_test.go │ ├── go.mod │ └── nrzap.go └── nrzerolog │ ├── LICENSE.md │ ├── README.md │ ├── example_test.go │ ├── go.mod │ └── nrzerolog.go ├── internal ├── awssupport │ ├── awssupport.go │ └── awssupport_test.go ├── cat │ ├── appdata.go │ ├── appdata_test.go │ ├── errors.go │ ├── headers.go │ ├── id.go │ ├── id_test.go │ ├── path_hash.go │ ├── path_hash_test.go │ ├── synthetics.go │ ├── synthetics_test.go │ ├── txndata.go │ └── txndata_test.go ├── com_newrelic_trace_v1 │ ├── README.md │ ├── v1.pb.go │ ├── v1.proto │ └── v1_grpc.pb.go ├── connect_reply.go ├── connect_reply_test.go ├── context.go ├── crossagent │ ├── README.md │ ├── cross_agent_tests │ │ ├── README.md │ │ ├── attribute_configuration.json │ │ ├── cat │ │ │ ├── README.md │ │ │ ├── cat_map.json │ │ │ └── path_hashing.json │ │ ├── collector_hostname.json │ │ ├── data_collection_server_configuration.json │ │ ├── datastores │ │ │ ├── README.md │ │ │ ├── datastore_api.json │ │ │ └── datastore_instances.json │ │ ├── distributed_tracing │ │ │ ├── README.md │ │ │ ├── distributed_tracing.json │ │ │ └── trace_context.json │ │ ├── docker_container_id │ │ │ ├── README.md │ │ │ ├── cases.json │ │ │ ├── docker-0.9.1.txt │ │ │ ├── docker-1.0.0.txt │ │ │ ├── docker-1.1.2-lxc-driver.txt │ │ │ ├── docker-1.1.2-native-driver-fs.txt │ │ │ ├── docker-1.1.2-native-driver-systemd.txt │ │ │ ├── docker-1.3.txt │ │ │ ├── docker-custom-prefix.txt │ │ │ ├── docker-gcp.txt │ │ │ ├── docker-too-long.txt │ │ │ ├── empty.txt │ │ │ ├── heroku.txt │ │ │ ├── invalid-characters.txt │ │ │ ├── invalid-length.txt │ │ │ ├── mountinfo.txt │ │ │ ├── no_cpu_subsystem.txt │ │ │ ├── ubuntu-14.04-lxc-container.txt │ │ │ ├── ubuntu-14.04-no-container.txt │ │ │ └── ubuntu-14.10-no-container.txt │ │ ├── labels.json │ │ ├── lambda │ │ │ ├── README.md │ │ │ └── event_source_info.json │ │ ├── language_agents_security_policies.json │ │ ├── postgres_explain_obfuscation │ │ │ ├── README.md │ │ │ ├── basic_where.colon_obfuscated.txt │ │ │ ├── basic_where.explain.txt │ │ │ ├── basic_where.obfuscated.txt │ │ │ ├── basic_where.query.txt │ │ │ ├── current_date.colon_obfuscated.txt │ │ │ ├── current_date.explain.txt │ │ │ ├── current_date.obfuscated.txt │ │ │ ├── current_date.query.txt │ │ │ ├── date.colon_obfuscated.txt │ │ │ ├── date.explain.txt │ │ │ ├── date.obfuscated.txt │ │ │ ├── date.query.txt │ │ │ ├── embedded_newline.colon_obfuscated.txt │ │ │ ├── embedded_newline.explain.txt │ │ │ ├── embedded_newline.obfuscated.txt │ │ │ ├── embedded_newline.query.txt │ │ │ ├── embedded_quote.colon_obfuscated.txt │ │ │ ├── embedded_quote.explain.txt │ │ │ ├── embedded_quote.obfuscated.txt │ │ │ ├── embedded_quote.query.txt │ │ │ ├── floating_point.colon_obfuscated.txt │ │ │ ├── floating_point.explain.txt │ │ │ ├── floating_point.obfuscated.txt │ │ │ ├── floating_point.query.txt │ │ │ ├── function_with_strings.colon_obfuscated.txt │ │ │ ├── function_with_strings.explain.txt │ │ │ ├── function_with_strings.obfuscated.txt │ │ │ ├── function_with_strings.query.txt │ │ │ ├── quote_in_table_name.colon_obfuscated.txt │ │ │ ├── quote_in_table_name.explain.txt │ │ │ ├── quote_in_table_name.obfuscated.txt │ │ │ ├── quote_in_table_name.query.txt │ │ │ ├── subplan.colon_obfuscated.txt │ │ │ ├── subplan.explain.txt │ │ │ ├── subplan.obfuscated.txt │ │ │ ├── subplan.query.txt │ │ │ ├── where_with_integer.colon_obfuscated.txt │ │ │ ├── where_with_integer.explain.txt │ │ │ ├── where_with_integer.obfuscated.txt │ │ │ ├── where_with_integer.query.txt │ │ │ ├── where_with_regex_chars.colon_obfuscated.txt │ │ │ ├── where_with_regex_chars.explain.txt │ │ │ ├── where_with_regex_chars.obfuscated.txt │ │ │ ├── where_with_regex_chars.query.txt │ │ │ ├── where_with_substring.colon_obfuscated.txt │ │ │ ├── where_with_substring.explain.txt │ │ │ ├── where_with_substring.obfuscated.txt │ │ │ ├── where_with_substring.query.txt │ │ │ ├── with_escape_case1.colon_obfuscated.txt │ │ │ ├── with_escape_case1.explain.txt │ │ │ ├── with_escape_case1.obfuscated.txt │ │ │ ├── with_escape_case1.query.txt │ │ │ ├── with_escape_case2.colon_obfuscated.txt │ │ │ ├── with_escape_case2.explain.txt │ │ │ ├── with_escape_case2.obfuscated.txt │ │ │ ├── with_escape_case2.query.txt │ │ │ ├── with_escape_case3.colon_obfuscated.txt │ │ │ ├── with_escape_case3.explain.txt │ │ │ ├── with_escape_case3.obfuscated.txt │ │ │ ├── with_escape_case3.query.txt │ │ │ ├── with_escape_case4.colon_obfuscated.txt │ │ │ ├── with_escape_case4.explain.txt │ │ │ ├── with_escape_case4.obfuscated.txt │ │ │ ├── with_escape_case4.query.txt │ │ │ ├── with_escape_case5.colon_obfuscated.txt │ │ │ ├── with_escape_case5.explain.txt │ │ │ ├── with_escape_case5.obfuscated.txt │ │ │ ├── with_escape_case5.query.txt │ │ │ ├── with_escape_case6.colon_obfuscated.txt │ │ │ ├── with_escape_case6.explain.txt │ │ │ ├── with_escape_case6.obfuscated.txt │ │ │ ├── with_escape_case6.query.txt │ │ │ ├── with_escape_case7.colon_obfuscated.txt │ │ │ ├── with_escape_case7.explain.txt │ │ │ ├── with_escape_case7.obfuscated.txt │ │ │ ├── with_escape_case7.query.txt │ │ │ ├── with_escape_case8.colon_obfuscated.txt │ │ │ ├── with_escape_case8.explain.txt │ │ │ ├── with_escape_case8.obfuscated.txt │ │ │ ├── with_escape_case8.query.txt │ │ │ ├── with_escape_case9.colon_obfuscated.txt │ │ │ ├── with_escape_case9.explain.txt │ │ │ ├── with_escape_case9.obfuscated.txt │ │ │ └── with_escape_case9.query.txt │ │ ├── proc_cpuinfo │ │ │ ├── 1pack_1core_1logical.txt │ │ │ ├── 1pack_1core_2logical.txt │ │ │ ├── 1pack_2core_2logical.txt │ │ │ ├── 1pack_4core_4logical.txt │ │ │ ├── 2pack_12core_24logical.txt │ │ │ ├── 2pack_20core_40logical.txt │ │ │ ├── 2pack_2core_2logical.txt │ │ │ ├── 2pack_2core_4logical.txt │ │ │ ├── 2pack_4core_4logical.txt │ │ │ ├── 4pack_4core_4logical.txt │ │ │ ├── 8pack_8core_8logical.txt │ │ │ ├── README.md │ │ │ ├── Xpack_Xcore_2logical.txt │ │ │ └── malformed_file.txt │ │ ├── proc_meminfo │ │ │ ├── README.md │ │ │ └── meminfo_4096MB.txt │ │ ├── rules.json │ │ ├── rum_client_config.json │ │ ├── rum_footer_insertion_location │ │ │ ├── close-body-in-comment.html │ │ │ └── dynamic-iframe.html │ │ ├── rum_loader_insertion_location │ │ │ ├── basic.html │ │ │ ├── body_with_attributes.html │ │ │ ├── charset_tag.html │ │ │ ├── charset_tag_after_x_ua_tag.html │ │ │ ├── charset_tag_before_x_ua_tag.html │ │ │ ├── charset_tag_with_spaces.html │ │ │ ├── comments1.html │ │ │ ├── comments2.html │ │ │ ├── content_type_charset_tag.html │ │ │ ├── content_type_charset_tag_after_x_ua_tag.html │ │ │ ├── content_type_charset_tag_before_x_ua_tag.html │ │ │ ├── gt_in_quotes1.html │ │ │ ├── gt_in_quotes2.html │ │ │ ├── gt_in_quotes_mismatch.html │ │ │ ├── gt_in_single_quotes1.html │ │ │ ├── gt_in_single_quotes_mismatch.html │ │ │ ├── head_with_attributes.html │ │ │ ├── incomplete_non_meta_tags.html │ │ │ ├── no_end_header.html │ │ │ ├── no_header.html │ │ │ ├── no_html_and_no_header.html │ │ │ ├── no_start_header.html │ │ │ ├── script1.html │ │ │ ├── script2.html │ │ │ ├── x_ua_meta_tag.html │ │ │ ├── x_ua_meta_tag_multiline.html │ │ │ ├── x_ua_meta_tag_multiple_tags.html │ │ │ ├── x_ua_meta_tag_spaces_around_equals.html │ │ │ ├── x_ua_meta_tag_with_others.html │ │ │ └── x_ua_meta_tag_with_spaces.html │ │ ├── sql_obfuscation │ │ │ ├── README.md │ │ │ └── sql_obfuscation.json │ │ ├── sql_parsing.json │ │ ├── synthetics │ │ │ ├── README.md │ │ │ └── synthetics.json │ │ ├── transaction_segment_terms.json │ │ ├── url_clean.json │ │ ├── url_domain_extraction.json │ │ ├── utilization │ │ │ ├── README.md │ │ │ ├── boot_id.json │ │ │ └── utilization_json.json │ │ └── utilization_vendor_specific │ │ │ ├── README.md │ │ │ ├── aws.json │ │ │ ├── azure.json │ │ │ ├── gcp.json │ │ │ └── pcf.json │ └── crossagent.go ├── expect.go ├── hidden_methods.go ├── integrationsupport │ ├── integrationsupport.go │ └── integrationsupport_test.go ├── jsonx │ ├── encode.go │ └── encode_test.go ├── limits.go ├── logcontext │ ├── decoratorTesting.go │ └── publicConstants.go ├── logger │ └── logger.go ├── message_metric_key.go ├── metric_rules.go ├── metric_rules_test.go ├── security_policies.go ├── security_policies_test.go ├── segment_terms.go ├── segment_terms_test.go ├── stacktracetest │ └── stacktracetest.go ├── sysinfo │ ├── bootid.go │ ├── docker.go │ ├── docker_test.go │ ├── errors.go │ ├── hostname.go │ ├── hostname_generic.go │ ├── hostname_linux.go │ ├── memtotal.go │ ├── memtotal_darwin.go │ ├── memtotal_darwin_test.go │ ├── memtotal_freebsd.go │ ├── memtotal_freebsd_test.go │ ├── memtotal_js.go │ ├── memtotal_linux.go │ ├── memtotal_openbsd_amd64.go │ ├── memtotal_openbsd_test.go │ ├── memtotal_solaris.go │ ├── memtotal_solaris_test.go │ ├── memtotal_test.go │ ├── memtotal_windows.go │ ├── usage.go │ ├── usage_js.go │ ├── usage_posix.go │ └── usage_windows.go ├── tools │ ├── interface-wrapping │ │ ├── driver_conn.json │ │ ├── driver_driver.json │ │ ├── driver_stmt.json │ │ ├── main.go │ │ └── response_writer.json │ └── rules │ │ └── main.go ├── trace_id_generator.go ├── trace_id_generator_test.go ├── usage.go ├── utilities.go ├── utilities_test.go └── utilization │ ├── addresses.go │ ├── aws.go │ ├── aws_test.go │ ├── azure.go │ ├── azure_test.go │ ├── fqdn.go │ ├── fqdn_pre18.go │ ├── gcp.go │ ├── gcp_test.go │ ├── pcf.go │ ├── pcf_test.go │ ├── provider.go │ ├── provider_test.go │ ├── utilization.go │ └── utilization_test.go └── newrelic ├── LICENSE.txt ├── adaptive_sampler.go ├── adaptive_sampler_test.go ├── analytics_events.go ├── analytics_events_test.go ├── apdex.go ├── apdex_test.go ├── app_run.go ├── app_run_test.go ├── application.go ├── attributes.go ├── attributes_from_internal.go ├── attributes_test.go ├── browser_header.go ├── browser_header_test.go ├── cat_test.go ├── code_level_metrics.go ├── code_level_metrics_test.go ├── collector.go ├── collector_test.go ├── config.go ├── config_options.go ├── config_options_test.go ├── config_test.go ├── context.go ├── cross_process_http.go ├── cross_process_http_test.go ├── custom_event.go ├── custom_event_test.go ├── custom_events.go ├── custom_metric.go ├── datastore.go ├── distributed_tracing.go ├── distributed_tracing_test.go ├── doc.go ├── environment.go ├── environment_test.go ├── error_events.go ├── error_events_test.go ├── error_group.go ├── errors.go ├── errors_from_internal.go ├── errors_test.go ├── examples_test.go ├── expect_implementation.go ├── harvest.go ├── harvest_test.go ├── instrumentation.go ├── internal_17_test.go ├── internal_app.go ├── internal_app_test.go ├── internal_attributes_test.go ├── internal_benchmark_test.go ├── internal_browser_test.go ├── internal_context_test.go ├── internal_cross_process_test.go ├── internal_distributed_trace_test.go ├── internal_errors_13_test.go ├── internal_errors_stacktrace_test.go ├── internal_errors_test.go ├── internal_response_writer.go ├── internal_response_writer_test.go ├── internal_segment_attributes_test.go ├── internal_serverless_test.go ├── internal_set_web_request_test.go ├── internal_set_web_response_test.go ├── internal_slow_queries_test.go ├── internal_span_events_test.go ├── internal_synthetics_test.go ├── internal_test.go ├── internal_txn.go ├── internal_txn_test.go ├── intrinsics.go ├── json_object_writer.go ├── json_object_writer_test.go ├── limits.go ├── log.go ├── log_event.go ├── log_event_test.go ├── log_events.go ├── log_events_test.go ├── metric_names.go ├── metrics.go ├── metrics_test.go ├── obfuscate.go ├── obfuscate_test.go ├── oom_monitor.go ├── priority.go ├── priority_test.go ├── queuing.go ├── queuing_test.go ├── rand.go ├── reservoir_limits_test.go ├── rules_cache.go ├── rules_cache_test.go ├── sampler.go ├── sampler_test.go ├── secure_agent.go ├── segments.go ├── serverless.go ├── serverless_from_internal.go ├── serverless_test.go ├── slow_queries.go ├── slow_queries_test.go ├── span_events.go ├── span_events_test.go ├── sql_driver.go ├── sql_driver_optional_methods.go ├── sql_driver_test.go ├── sqlparse ├── sqlparse.go └── sqlparse_test.go ├── stacktrace.go ├── stacktrace_test.go ├── synthetics_test.go ├── trace_context_test.go ├── trace_observer.go ├── trace_observer_1_8.go ├── trace_observer_1_8_test.go ├── trace_observer_common.go ├── trace_observer_impl_test.go ├── trace_observer_test.go ├── tracing.go ├── tracing_test.go ├── transaction.go ├── transaction_test.go ├── transport.go ├── transport_1_12.go ├── txn_cross_process.go ├── txn_cross_process_test.go ├── txn_events.go ├── txn_events_test.go ├── txn_trace.go ├── txn_trace_test.go ├── url.go ├── url_test.go ├── utilities.go ├── utilities_test.go └── version.go /.github/ISSUE_TEMPLATE/bug-report---.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug report \U0001F41B" 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | [NOTE]: # ( ^^ Provide a general summary of the issue in the title above. ^^ ) 11 | 12 | ## Description 13 | 14 | [NOTE]: # ( Describe the problem you're encountering. ) 15 | [TIP]: # ( Do NOT give us access or passwords to your New Relic account or API keys! ) 16 | 17 | ## Steps to Reproduce 18 | 19 | [NOTE]: # ( Please be as specific as possible. ) 20 | 21 | ## Expected Behavior 22 | 23 | [NOTE]: # ( Tell us what you expected to happen. ) 24 | 25 | ## NR Diag results 26 | 27 | [NOTE]: # ( Provide any other relevant log data. ) 28 | 29 | ## Your Environment 30 | 31 | [TIP]: # ( Include as many relevant details about your environment as possible including the running version of New Relic software and any relevant configurations. ) 32 | 33 | ## Reproduction case 34 | 35 | [TIP]: # ( Link a sample application that demonstrates the issue. ) 36 | 37 | ## Additional context 38 | 39 | [TIP]: # ( Add any other context about the problem here. ) 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Troubleshooting 4 | url: https://github.com/newrelic/go-agent/blob/master/README.md#support 5 | about: checkout the README for troubleshooting directions 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement-request---.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Enhancement request \U0001F4A1" 3 | about: Suggest an idea for a future version of this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | [NOTE]: # ( ^^ Provide a general summary of the request in the title above. ^^ ) 11 | 12 | ## Summary 13 | 14 | [NOTE]: # ( Provide a brief overview of what the new feature is all about. ) 15 | 16 | ## Desired Behaviour 17 | 18 | [NOTE]: # ( Tell us how the new feature should work. Be specific. ) 19 | [TIP]: # ( Do NOT give us access or passwords to your New Relic account or API keys! ) 20 | 21 | ## Possible Solution 22 | 23 | [NOTE]: # ( Not required. Suggest how to implement the addition or change. ) 24 | 25 | ## Additional context 26 | 27 | [TIP]: # ( Why does this feature matter to you? What unique circumstances do you have? ) 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/troubleshooting.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | We use GitHub to track feature requests and bug reports. Please **do not** submit issues for questions about how to configure, use features, troubleshoot, or best practices for using New Relic software. 4 | 5 | See the README.md troubleshooting section in this repository for more details on self-service troubleshooting tooling, links to our comprehenive documentation, and how to get further support. 6 | 7 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 14 | 15 | ## Links 16 | 17 | 20 | 21 | ## Details 22 | 23 | 26 | -------------------------------------------------------------------------------- /.github/auto_assign.yml: -------------------------------------------------------------------------------- 1 | # Set to true to add reviewers to pull requests 2 | addReviewers: true 3 | 4 | # Set to true to add assignees to pull requests 5 | addAssignees: true 6 | 7 | # A list of reviewers to be added to pull requests (GitHub user name) 8 | reviewers: 9 | - iamemilio 10 | - mirackara 11 | - nr-swilloughby 12 | 13 | # A number of reviewers added to the pull request 14 | # Set 0 to add all the reviewers (default: 0) 15 | numberOfReviewers: 1 16 | # A list of assignees, overrides reviewers if set 17 | # assignees: 18 | # - assigneeA 19 | 20 | # A number of assignees to add to the pull request 21 | # Set to 0 to add all of the assignees. 22 | # Uses numberOfReviewers if unset. 23 | # numberOfAssignees: 2 24 | 25 | # A list of keywords to be skipped the process that add reviewers if pull requests include it 26 | # skipKeywords: 27 | # - wip 28 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | # Disable version updates for gomod dependencies, security updates don't use this configuration 5 | # See: https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates 6 | open-pull-requests-limit: 0 7 | directory: "../v3" 8 | schedule: 9 | interval: "daily" 10 | commit-message: 11 | prefix: "security" 12 | prefix-development: "chore" 13 | include: "scope" 14 | -------------------------------------------------------------------------------- /.github/workflows/autoassign.yml: -------------------------------------------------------------------------------- 1 | name: 'Auto Assign' 2 | on: 3 | pull_request: 4 | types: [opened, ready_for_review] 5 | 6 | jobs: 7 | add-reviews: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: kentaro-m/auto-assign-action@v2.0.0 11 | -------------------------------------------------------------------------------- /.github/workflows/repolinter.yml: -------------------------------------------------------------------------------- 1 | # NOTE: This file should always be named `repolinter.yml` to allow 2 | # workflow_dispatch to work properly 3 | name: Repolinter Action 4 | 5 | # NOTE: This workflow will ONLY check the default branch! 6 | # Currently there is no elegant way to specify the default 7 | # branch in the event filtering, so branches are instead 8 | # filtered in the "Test Default Branch" step. 9 | on: [push, workflow_dispatch] 10 | 11 | jobs: 12 | repolint: 13 | name: Run Repolinter 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Test Default Branch 17 | id: default-branch 18 | uses: actions/github-script@v2 19 | with: 20 | script: | 21 | const data = await github.repos.get(context.repo) 22 | return data.data && data.data.default_branch === context.ref.split('/').slice(-1)[0] 23 | - name: Checkout Self 24 | if: ${{ steps.default-branch.outputs.result == 'true' }} 25 | uses: actions/checkout@v2 26 | - name: Run Repolinter 27 | if: ${{ steps.default-branch.outputs.result == 'true' }} 28 | uses: newrelic/repolinter-action@v1 29 | with: 30 | config_url: https://raw.githubusercontent.com/newrelic/.github/main/repolinter-rulesets/community-plus.yml 31 | output_type: issue 32 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | go.sum -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This file is used to build the docker image for the Go Agent's GitHub Action tests 2 | # Default go version if no arguments passed in 3 | ARG GO_VERSION=1.20 4 | 5 | # Takes in go version 6 | FROM golang:${GO_VERSION} as builder 7 | 8 | # Set working directory and run go mod tidy 9 | WORKDIR /app 10 | # Copy source code files 11 | COPY . . 12 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: true 4 | patch: true 5 | changes: false 6 | 7 | ignore: 8 | - "go-agent/v3/newrelic/sql_driver_optional_methods.go" 9 | 10 | comment: 11 | layout: "reach,diff,flags,files,footer" 12 | behavior: default 13 | require_changes: false -------------------------------------------------------------------------------- /run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # run_tests.sh 3 | export PATH=$PATH:/usr/local/go/bin 4 | # Test directory is passed in as an argument 5 | TEST_DIR=$1 6 | 7 | # Function for checking Go Code Formatting 8 | verify_go_fmt() { 9 | needsFMT=$(gofmt -d .) 10 | if [ ! -z "$needsFMT" ]; then 11 | echo "$needsFMT" 12 | echo "Please format your code with \"gofmt .\"" 13 | # exit 1 14 | fi 15 | } 16 | 17 | # Replace go-agent with local pull 18 | cd go-agent/v3 19 | go mod edit -replace github.com/newrelic/go-agent/v3="$(pwd)/v3" 20 | cd ../ 21 | cd $TEST_DIR 22 | 23 | go mod tidy 24 | # Run Tests and Create Cover Profile for Code Coverage 25 | go test -race -benchtime=1ms -bench=. ./... 26 | go vet ./... 27 | verify_go_fmt -------------------------------------------------------------------------------- /v3/examples/client/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "net/http" 9 | "os" 10 | "time" 11 | 12 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 13 | ) 14 | 15 | func doRequest(txn *newrelic.Transaction) error { 16 | req, err := http.NewRequest("GET", "http://localhost:8000/segments", nil) 17 | if err != nil { 18 | return err 19 | } 20 | client := &http.Client{} 21 | seg := newrelic.StartExternalSegment(txn, req) 22 | defer seg.End() 23 | resp, err := client.Do(req) 24 | if err != nil { 25 | return err 26 | } 27 | fmt.Println("response code is", resp.StatusCode) 28 | return nil 29 | } 30 | 31 | func main() { 32 | app, err := newrelic.NewApplication( 33 | newrelic.ConfigAppName("Client App"), 34 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 35 | newrelic.ConfigDebugLogger(os.Stdout), 36 | newrelic.ConfigDistributedTracerEnabled(true), 37 | ) 38 | if err != nil { 39 | fmt.Println(err) 40 | os.Exit(1) 41 | } 42 | 43 | txn := app.StartTransaction("client-txn") 44 | err = doRequest(txn) 45 | if err != nil { 46 | txn.NoticeError(err) 47 | } 48 | txn.End() 49 | 50 | // Shut down the application to flush data to New Relic. 51 | app.Shutdown(10 * time.Second) 52 | } 53 | -------------------------------------------------------------------------------- /v3/examples/short-lived-process/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "time" 10 | 11 | "github.com/newrelic/go-agent/v3/newrelic" 12 | ) 13 | 14 | func main() { 15 | app, err := newrelic.NewApplication( 16 | newrelic.ConfigAppName("Short Lived App"), 17 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 18 | newrelic.ConfigDebugLogger(os.Stdout), 19 | ) 20 | if nil != err { 21 | fmt.Println(err) 22 | os.Exit(1) 23 | } 24 | 25 | // Wait for the application to connect. 26 | if err := app.WaitForConnection(5 * time.Second); nil != err { 27 | fmt.Println(err) 28 | } 29 | 30 | // Do the tasks at hand. Perhaps record them using transactions and/or 31 | // custom events. 32 | tasks := []string{"white", "black", "red", "blue", "green", "yellow"} 33 | for _, task := range tasks { 34 | txn := app.StartTransaction("task") 35 | time.Sleep(10 * time.Millisecond) 36 | txn.End() 37 | app.RecordCustomEvent("task", map[string]interface{}{ 38 | "color": task, 39 | }) 40 | } 41 | 42 | // Shut down the application to flush data to New Relic. 43 | app.Shutdown(10 * time.Second) 44 | } 45 | -------------------------------------------------------------------------------- /v3/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3 2 | 3 | go 1.22 4 | 5 | require ( 6 | google.golang.org/grpc v1.65.0 7 | google.golang.org/protobuf v1.34.2 8 | ) 9 | 10 | 11 | retract v3.22.0 // release process error corrected in v3.22.1 12 | 13 | retract v3.25.0 // release process error corrected in v3.25.1 14 | 15 | retract v3.34.0 // this release erronously referred to and invalid protobuf dependency 16 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/logWriter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/logWriter 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrlogrus/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrlogrus 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/sirupsen/logrus v1.8.1 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrslog/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log/slog" 6 | "os" 7 | "time" 8 | 9 | "github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog" 10 | "github.com/newrelic/go-agent/v3/newrelic" 11 | ) 12 | 13 | func main() { 14 | app, err := newrelic.NewApplication( 15 | newrelic.ConfigAppName("slog example app"), 16 | newrelic.ConfigFromEnvironment(), 17 | newrelic.ConfigAppLogEnabled(true), 18 | ) 19 | if err != nil { 20 | panic(err) 21 | } 22 | 23 | app.WaitForConnection(time.Second * 5) 24 | 25 | handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}) 26 | nrHandler := nrslog.WrapHandler(app, handler) 27 | log := slog.New(nrHandler) 28 | 29 | log.Info("I am a log message") 30 | 31 | txn := app.StartTransaction("example transaction") 32 | ctx := newrelic.NewContext(context.Background(), txn) 33 | 34 | log.InfoContext(ctx, "I am a log inside a transaction with custom attributes!", 35 | slog.String("foo", "bar"), 36 | slog.Int("answer", 42), 37 | slog.Any("some_map", map[string]interface{}{"a": 1.0, "b": 2}), 38 | ) 39 | 40 | // pretend to do some work 41 | time.Sleep(500 * time.Millisecond) 42 | log.Warn("Uh oh, something important happened!") 43 | txn.End() 44 | 45 | log.Info("All Done!") 46 | 47 | app.Shutdown(time.Second * 10) 48 | } 49 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrslog/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrslog 2 | 3 | go 1.22 4 | 5 | require github.com/newrelic/go-agent/v3 v3.39.0 6 | 7 | 8 | replace github.com/newrelic/go-agent/v3 => ../../.. 9 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrwriter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter 2 | 3 | go 1.22 4 | 5 | require github.com/newrelic/go-agent/v3 v3.39.0 6 | 7 | 8 | replace github.com/newrelic/go-agent/v3 => ../../.. 9 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrzap/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzap 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | go.uber.org/zap v1.24.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrzerolog/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "time" 8 | 9 | "github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzerolog" 10 | "github.com/newrelic/go-agent/v3/newrelic" 11 | "github.com/rs/zerolog" 12 | ) 13 | 14 | func main() { 15 | baseLogger := zerolog.New(os.Stdout) 16 | 17 | app, err := newrelic.NewApplication( 18 | newrelic.ConfigFromEnvironment(), 19 | newrelic.ConfigAppName("NRZerolog Example"), 20 | newrelic.ConfigInfoLogger(os.Stdout), 21 | newrelic.ConfigAppLogForwardingEnabled(true), 22 | ) 23 | if err != nil { 24 | fmt.Println(err) 25 | os.Exit(1) 26 | } 27 | 28 | app.WaitForConnection(5 * time.Second) 29 | 30 | nrHook := nrzerolog.NewRelicHook{ 31 | App: app, 32 | } 33 | 34 | nrLogger := baseLogger.Hook(nrHook) 35 | nrLogger.Info().Msg("Hello World") 36 | 37 | // With transaction context 38 | txn := app.StartTransaction("My Transaction") 39 | ctx := newrelic.NewContext(context.Background(), txn) 40 | 41 | nrTxnHook := nrzerolog.NewRelicHook{ 42 | App: app, 43 | Context: ctx, 44 | } 45 | 46 | txnLogger := baseLogger.Hook(nrTxnHook) 47 | txnLogger.Debug().Msg("This is a transaction log") 48 | 49 | txn.End() 50 | 51 | nrLogger.Info().Msg("Goodbye") 52 | app.Shutdown(10 * time.Second) 53 | } 54 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrzerolog/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrzerolog 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/rs/zerolog v1.26.1 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/nrzerolog/hook.go: -------------------------------------------------------------------------------- 1 | package nrzerolog 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/newrelic/go-agent/v3/internal" 7 | "github.com/newrelic/go-agent/v3/newrelic" 8 | "github.com/rs/zerolog" 9 | ) 10 | 11 | func init() { internal.TrackUsage("integration", "logcontext-v2", "zerolog") } 12 | 13 | type NewRelicHook struct { 14 | App *newrelic.Application 15 | Context context.Context 16 | } 17 | 18 | func (h NewRelicHook) Run(e *zerolog.Event, level zerolog.Level, msg string) { 19 | var txn *newrelic.Transaction 20 | if h.Context != nil { 21 | txn = newrelic.FromContext(h.Context) 22 | } 23 | 24 | logLevel := "" 25 | if level != zerolog.NoLevel { 26 | logLevel = level.String() 27 | } 28 | 29 | data := newrelic.LogData{ 30 | Severity: logLevel, 31 | Message: msg, 32 | } 33 | 34 | if txn != nil { 35 | txn.RecordLog(data) 36 | } else { 37 | h.App.RecordLog(data) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/zerologWriter/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "time" 6 | 7 | "github.com/newrelic/go-agent/v3/integrations/logcontext-v2/zerologWriter" 8 | "github.com/newrelic/go-agent/v3/newrelic" 9 | "github.com/rs/zerolog" 10 | ) 11 | 12 | func main() { 13 | app, err := newrelic.NewApplication( 14 | newrelic.ConfigAppName("nrwriter log writer example"), 15 | newrelic.ConfigFromEnvironment(), 16 | newrelic.ConfigInfoLogger(os.Stdout), 17 | newrelic.ConfigAppLogDecoratingEnabled(true), 18 | ) 19 | if err != nil { 20 | panic(err) 21 | } 22 | 23 | app.WaitForConnection(5 * time.Second) 24 | 25 | writer := zerologWriter.New(os.Stdout, app) 26 | logger := zerolog.New(writer) 27 | 28 | logger.Print("Application connected to New Relic.") 29 | 30 | txnName := "Example Transaction" 31 | txn := app.StartTransaction(txnName) 32 | 33 | // Always create a new logger in order to avoid changing the context of the logger for 34 | // other threads that may be logging outside of this transaction 35 | txnLogger := logger.Output(writer.WithTransaction(txn)) 36 | txnLogger.Printf("In transaction %s.", txnName) 37 | 38 | // simulate doing something 39 | time.Sleep(time.Microsecond * 100) 40 | 41 | txnLogger.Printf("Ending transaction %s.", txnName) 42 | txn.End() 43 | 44 | app.Shutdown(10 * time.Second) 45 | } 46 | -------------------------------------------------------------------------------- /v3/integrations/logcontext-v2/zerologWriter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext-v2/zerologWriter 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrwriter v1.0.0 8 | github.com/rs/zerolog v1.27.0 9 | ) 10 | 11 | 12 | replace github.com/newrelic/go-agent/v3 => ../../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/logcontext/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/logcontext [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext) 2 | 3 | Logs in Context. Each directory represents a different logging plugin. 4 | Plugins allow you to add the context required to your log messages so you can 5 | see linking in the APM UI. 6 | 7 | For more information, see 8 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext). 9 | -------------------------------------------------------------------------------- /v3/integrations/logcontext/nrlogrusplugin/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/logcontext/nrlogrusplugin [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin) 2 | 3 | Package `nrlogrusplugin` decorates logs for sending to the New Relic backend. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin). 11 | -------------------------------------------------------------------------------- /v3/integrations/logcontext/nrlogrusplugin/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/logcontext/nrlogrusplugin 2 | 3 | // As of Dec 2019, the logrus go.mod file uses 1.13: 4 | // https://github.com/sirupsen/logrus/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | // v1.4.0 is required for for the log.WithContext. 10 | github.com/sirupsen/logrus v1.4.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nramqp/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nramqp 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/rabbitmq/amqp091-go v1.9.0 8 | ) 9 | replace github.com/newrelic/go-agent/v3 => ../.. 10 | -------------------------------------------------------------------------------- /v3/integrations/nrawsbedrock/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrawsbedrock [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawsbedrock?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawsbedrock) 2 | 3 | Package `nrawsbedrock` instruments https://github.com/aws/aws-sdk-go-v2/service/bedrockruntime requests. 4 | 5 | This integration works independently of the `nrawssdk-v2` integration, which instruments AWS middleware components generally, while this one instruments Bedrock AI model invocations specifically and in detail. 6 | 7 | ```go 8 | import "github.com/newrelic/go-agent/v3/integrations/nrawsbedrock" 9 | ``` 10 | 11 | For more information, see 12 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawsbedrock). 13 | -------------------------------------------------------------------------------- /v3/integrations/nrawsbedrock/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrawsbedrock 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go-v2 v1.26.0 7 | github.com/aws/aws-sdk-go-v2/config v1.27.4 8 | github.com/aws/aws-sdk-go-v2/service/bedrock v1.7.3 9 | github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.7.1 10 | github.com/google/uuid v1.6.0 11 | github.com/newrelic/go-agent/v3 v3.39.0 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrawssdk-v1/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrawssdk-v1 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1) 2 | 3 | Package `nrawssdk` instruments https://github.com/aws/aws-sdk-go requests. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrawssdk-v1/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrawssdk-v1 2 | 3 | // As of Dec 2019, aws-sdk-go's go.mod does not specify a Go version. 1.6 is 4 | // the earliest version of Go tested by aws-sdk-go's CI: 5 | // https://github.com/aws/aws-sdk-go/blob/master/.travis.yml 6 | go 1.22 7 | 8 | require ( 9 | // v1.15.0 is the first aws-sdk-go version with module support. 10 | github.com/aws/aws-sdk-go v1.34.0 11 | github.com/newrelic/go-agent/v3 v3.39.0 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrawssdk-v2/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrawssdk-v2 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2) 2 | 3 | Package `nrawssdk` instruments https://github.com/aws/aws-sdk-go-v2 requests. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrawssdk-v2/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrawssdk-v2 2 | 3 | // As of May 2021, the aws-sdk-go-v2 go.mod file uses 1.15: 4 | // https://github.com/aws/aws-sdk-go-v2/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/aws/aws-sdk-go-v2 v1.30.4 9 | github.com/aws/aws-sdk-go-v2/config v1.27.31 10 | github.com/aws/aws-sdk-go-v2/service/dynamodb v1.34.6 11 | github.com/aws/aws-sdk-go-v2/service/lambda v1.58.1 12 | github.com/aws/aws-sdk-go-v2/service/s3 v1.61.0 13 | github.com/aws/aws-sdk-go-v2/service/sqs v1.34.6 14 | github.com/aws/smithy-go v1.20.4 15 | github.com/newrelic/go-agent/v3 v3.39.0 16 | ) 17 | 18 | 19 | replace github.com/newrelic/go-agent/v3 => ../.. 20 | -------------------------------------------------------------------------------- /v3/integrations/nrb3/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrb3 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrb3?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrb3) 2 | 3 | Package `nrb3` supports adding B3 headers to outgoing requests. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrb3" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrb3). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrb3/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrb3_test 5 | 6 | import ( 7 | "fmt" 8 | "log" 9 | "net/http" 10 | 11 | "github.com/newrelic/go-agent/v3/integrations/nrb3" 12 | "github.com/newrelic/go-agent/v3/newrelic" 13 | ) 14 | 15 | func currentTxn() *newrelic.Transaction { 16 | return nil 17 | } 18 | 19 | func ExampleNewRoundTripper() { 20 | // When defining the client, set the Transport to the NewRoundTripper. This 21 | // will create ExternalSegments and add B3 headers for each request. 22 | client := &http.Client{ 23 | Transport: nrb3.NewRoundTripper(nil), 24 | } 25 | 26 | // Distributed Tracing must be enabled for this application. 27 | txn := currentTxn() 28 | 29 | req, err := http.NewRequest("GET", "http://example.com", nil) 30 | if nil != err { 31 | log.Fatalln(err) 32 | } 33 | 34 | // Be sure to add the transaction to the request context. This step is 35 | // required. 36 | req = newrelic.RequestWithTransactionContext(req, txn) 37 | resp, err := client.Do(req) 38 | if nil != err { 39 | log.Fatalln(err) 40 | } 41 | 42 | defer resp.Body.Close() 43 | fmt.Println(resp.StatusCode) 44 | } 45 | -------------------------------------------------------------------------------- /v3/integrations/nrb3/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrb3 2 | 3 | go 1.22 4 | 5 | require github.com/newrelic/go-agent/v3 v3.39.0 6 | 7 | 8 | replace github.com/newrelic/go-agent/v3 => ../.. 9 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v3/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrecho-v3 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v3?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v3) 2 | 3 | Package `nrecho` instruments applications using https://github.com/labstack/echo v3. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrecho-v3" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v3). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v3/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "net/http" 9 | "os" 10 | 11 | "github.com/labstack/echo" 12 | "github.com/newrelic/go-agent/v3/integrations/nrecho-v3" 13 | "github.com/newrelic/go-agent/v3/newrelic" 14 | ) 15 | 16 | func getUser(c echo.Context) error { 17 | id := c.Param("id") 18 | 19 | txn := nrecho.FromContext(c) 20 | txn.AddAttribute("userId", id) 21 | 22 | return c.String(http.StatusOK, id) 23 | } 24 | 25 | func main() { 26 | app, err := newrelic.NewApplication( 27 | newrelic.ConfigAppName("Echo App"), 28 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 29 | newrelic.ConfigDebugLogger(os.Stdout), 30 | ) 31 | if nil != err { 32 | fmt.Println(err) 33 | os.Exit(1) 34 | } 35 | 36 | // Echo instance 37 | e := echo.New() 38 | 39 | // The New Relic Middleware should be the first middleware registered 40 | e.Use(nrecho.Middleware(app)) 41 | 42 | // Routes 43 | e.GET("/home", func(c echo.Context) error { 44 | return c.String(http.StatusOK, "Hello, World!") 45 | }) 46 | 47 | // Groups 48 | g := e.Group("/user") 49 | g.GET("/:id", getUser) 50 | 51 | // Start server 52 | e.Start(":8000") 53 | } 54 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v3/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrecho-v3 2 | 3 | // 1.7 is the earliest version of Go tested by v3.1.0: 4 | // https://github.com/labstack/echo/blob/v3.1.0/.travis.yml 5 | go 1.22 6 | 7 | require ( 8 | // v3.1.0 is the earliest v3 version of Echo that works with modules due 9 | // to the github.com/rsc/letsencrypt import of v3.0.0. 10 | github.com/labstack/echo v3.1.0+incompatible 11 | github.com/newrelic/go-agent/v3 v3.39.0 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v4/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrecho-v4 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v4?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v4) 2 | 3 | Package `nrecho` instruments applications using https://github.com/labstack/echo v4. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrecho-v4" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrecho-v4). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v4/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "net/http" 9 | "os" 10 | 11 | "github.com/labstack/echo/v4" 12 | "github.com/newrelic/go-agent/v3/integrations/nrecho-v4" 13 | "github.com/newrelic/go-agent/v3/newrelic" 14 | ) 15 | 16 | func getUser(c echo.Context) error { 17 | id := c.Param("id") 18 | 19 | txn := nrecho.FromContext(c) 20 | txn.AddAttribute("userId", id) 21 | 22 | return c.String(http.StatusOK, id) 23 | } 24 | 25 | func main() { 26 | app, err := newrelic.NewApplication( 27 | newrelic.ConfigAppName("Echo App"), 28 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 29 | newrelic.ConfigDebugLogger(os.Stdout), 30 | ) 31 | if nil != err { 32 | fmt.Println(err) 33 | os.Exit(1) 34 | } 35 | 36 | // Echo instance 37 | e := echo.New() 38 | 39 | // The New Relic Middleware should be the first middleware registered 40 | e.Use(nrecho.Middleware(app)) 41 | 42 | // Routes 43 | e.GET("/home", func(c echo.Context) error { 44 | return c.String(http.StatusOK, "Hello, World!") 45 | }) 46 | 47 | // Groups 48 | g := e.Group("/user") 49 | g.GET("/:id", getUser) 50 | 51 | // Start server 52 | e.Start(":8000") 53 | } 54 | -------------------------------------------------------------------------------- /v3/integrations/nrecho-v4/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrecho-v4 2 | 3 | // As of Jun 2022, the echo go.mod file uses 1.17: 4 | // https://github.com/labstack/echo/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/labstack/echo/v4 v4.9.0 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrelasticsearch-v7/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrelasticsearch-v7 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7) 2 | 3 | Package `nrelasticsearch` instruments `"github.com/elastic/go-elasticsearch/v7"`. 4 | 5 | ```go 6 | import nrelasticsearch "github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrelasticsearch-v7/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrelasticsearch_test 5 | 6 | import ( 7 | "context" 8 | 9 | elasticsearch "github.com/elastic/go-elasticsearch/v7" 10 | nrelasticsearch "github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7" 11 | "github.com/newrelic/go-agent/v3/newrelic" 12 | ) 13 | 14 | func getTransaction() *newrelic.Transaction { return nil } 15 | 16 | func Example() { 17 | // Step 1: Use nrelasticsearch.NewRoundTripper to assign the 18 | // elasticsearch.Config's Transport field. 19 | cfg := elasticsearch.Config{ 20 | Transport: nrelasticsearch.NewRoundTripper(nil), 21 | } 22 | client, err := elasticsearch.NewClient(cfg) 23 | if err != nil { 24 | panic(err) 25 | } 26 | // Step 2: Ensure that all calls using the elasticsearch client have 27 | // a context which includes the newrelic.Transaction. 28 | txn := getTransaction() 29 | ctx := newrelic.NewContext(context.Background(), txn) 30 | client.Info(client.Info.WithContext(ctx)) 31 | } 32 | -------------------------------------------------------------------------------- /v3/integrations/nrelasticsearch-v7/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrelasticsearch-v7 2 | 3 | // As of Jan 2020, the v7 elasticsearch go.mod uses 1.11: 4 | // https://github.com/elastic/go-elasticsearch/blob/7.x/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/elastic/go-elasticsearch/v7 v7.17.0 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrfasthttp/examples/client-fasthttp/go.mod: -------------------------------------------------------------------------------- 1 | module client-example 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 8 | github.com/valyala/fasthttp v1.49.0 9 | ) 10 | 11 | replace github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 => ../../ 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../../../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrfasthttp/examples/server-fasthttp/go.mod: -------------------------------------------------------------------------------- 1 | module server-example 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 8 | github.com/valyala/fasthttp v1.49.0 9 | ) 10 | 11 | replace github.com/newrelic/go-agent/v3/integrations/nrfasthttp v1.0.0 => ../../ 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../../../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrfasthttp/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrfasthttp 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/valyala/fasthttp v1.49.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrfiber/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrfiber [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrfiber?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrfiber) 2 | 3 | Package `nrfiber` instruments https://github.com/gofiber/fiber applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrfiber" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrfiber). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrfiber/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrfiber 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/gofiber/fiber/v2 v2.52.6 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/stretchr/testify v1.10.0 9 | github.com/valyala/fasthttp v1.51.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrgin/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrgin [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgin?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgin) 2 | 3 | Package `nrgin` instruments https://github.com/gin-gonic/gin applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrgin" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgin). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrgin/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgin 2 | 3 | // As of Dec 2019, the gin go.mod file uses 1.12: 4 | // https://github.com/gin-gonic/gin/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/gin-gonic/gin v1.9.1 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrgochi/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgochi 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/go-chi/chi/v5 v5.2.1 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | ) 9 | 10 | replace github.com/newrelic/go-agent/v3 => ../.. 11 | -------------------------------------------------------------------------------- /v3/integrations/nrgorilla/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrgorilla [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgorilla?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgorilla) 2 | 3 | Package `nrgorilla` instruments https://github.com/gorilla/mux applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrgorilla" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgorilla). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrgorilla/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgorilla 2 | 3 | // As of Dec 2019, the gorilla/mux go.mod file uses 1.12: 4 | // https://github.com/gorilla/mux/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | // v1.7.0 is the earliest version of Gorilla using modules. 9 | github.com/gorilla/mux v1.7.0 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrgraphgophers/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrgraphgophers [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphgophers?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphgophers) 2 | 3 | Package `nrgraphgophers` instruments https://github.com/graph-gophers/graphql-go applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrgraphgophers" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphgophers). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrgraphgophers/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgraphgophers 2 | 3 | // As of Jan 2020, the graphql-go go.mod file uses 1.13: 4 | // https://github.com/graph-gophers/graphql-go/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | // graphql-go has no tagged releases as of Jan 2020. 9 | github.com/graph-gophers/graphql-go v1.3.0 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrgraphqlgo/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrgraphqlgo [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo) 2 | 3 | Package `nrgraphql` instruments https://github.com/graphql-go/graphql applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo" 7 | ``` 8 | 9 | Note that New Relic has support for more than one GraphQL framework, and both 10 | packages are named `nrgraphql`, so please ensure you are using the 11 | integration for the correct framework. 12 | 13 | For more information, see 14 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo). 15 | -------------------------------------------------------------------------------- /v3/integrations/nrgraphqlgo/example/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo/example 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/graphql-go/graphql v0.8.1 7 | github.com/graphql-go/graphql-go-handler v0.2.3 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo v1.0.0 10 | ) 11 | 12 | replace github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo => ../ 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrgraphqlgo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgraphqlgo 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/graphql-go/graphql v0.8.1 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrgrpc/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrgrpc [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgrpc?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgrpc) 2 | 3 | Package `nrgrpc` instruments https://github.com/grpc/grpc-go. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrgrpc" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrgrpc). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrgrpc/example/sampleapp/sampleapp.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | service SampleApplication { 7 | rpc DoUnaryUnary(Message) returns (Message) {} 8 | rpc DoUnaryStream(Message) returns (stream Message) {} 9 | rpc DoStreamUnary(stream Message) returns (Message) {} 10 | rpc DoStreamStream(stream Message) returns (stream Message) {} 11 | } 12 | 13 | message Message { 14 | string text = 1; 15 | } 16 | -------------------------------------------------------------------------------- /v3/integrations/nrgrpc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrgrpc 2 | 3 | go 1.22 4 | 5 | require ( 6 | // protobuf v1.3.0 is the earliest version using modules, we use v1.3.1 7 | // because all dependencies were removed in this version. 8 | github.com/golang/protobuf v1.5.4 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | github.com/newrelic/go-agent/v3/integrations/nrsecurityagent v1.1.0 11 | // v1.15.0 is the earliest version of grpc using modules. 12 | google.golang.org/grpc v1.65.0 13 | google.golang.org/protobuf v1.34.2 14 | ) 15 | 16 | 17 | replace github.com/newrelic/go-agent/v3/integrations/nrsecurityagent => ../../integrations/nrsecurityagent 18 | 19 | replace github.com/newrelic/go-agent/v3 => ../.. 20 | -------------------------------------------------------------------------------- /v3/integrations/nrgrpc/testapp/README.md: -------------------------------------------------------------------------------- 1 | # Testing gRPC Application 2 | 3 | This directory contains a testing application for validating the New Relic gRPC 4 | integration. The code in `testapp.pb.go` is generated using the following 5 | command (to be run from the `v3/integrations/nrgrpc` directory). This command 6 | should be rerun every time the `testapp.proto` file has changed for any reason. 7 | 8 | ```bash 9 | $ protoc -I testapp/ testapp/testapp.proto --go_out=plugins=grpc:testapp 10 | ``` 11 | 12 | To install required dependencies: 13 | 14 | ```bash 15 | go get -u google.golang.org/grpc 16 | go get -u github.com/golang/protobuf/protoc-gen-go 17 | ``` 18 | -------------------------------------------------------------------------------- /v3/integrations/nrgrpc/testapp/testapp.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | service TestApplication { 7 | rpc DoUnaryUnary(Message) returns (Message) {} 8 | rpc DoUnaryStream(Message) returns (stream Message) {} 9 | rpc DoStreamUnary(stream Message) returns (Message) {} 10 | rpc DoStreamStream(stream Message) returns (stream Message) {} 11 | 12 | rpc DoUnaryUnaryError(Message) returns (Message) {} 13 | rpc DoUnaryStreamError(Message) returns (stream Message) {} 14 | } 15 | 16 | message Message { 17 | string text = 1; 18 | } 19 | -------------------------------------------------------------------------------- /v3/integrations/nrhttprouter/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrhttprouter [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrhttprouter?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrhttprouter) 2 | 3 | Package `nrhttprouter` instruments https://github.com/julienschmidt/httprouter applications. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrhttprouter" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrhttprouter). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrhttprouter/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "net/http" 9 | "os" 10 | 11 | "github.com/julienschmidt/httprouter" 12 | "github.com/newrelic/go-agent/v3/integrations/nrhttprouter" 13 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 14 | ) 15 | 16 | func index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { 17 | w.Write([]byte("welcome\n")) 18 | } 19 | 20 | func hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { 21 | w.Write([]byte(fmt.Sprintf("hello %s\n", ps.ByName("name")))) 22 | } 23 | 24 | func main() { 25 | app, err := newrelic.NewApplication( 26 | newrelic.ConfigAppName("httprouter App"), 27 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 28 | newrelic.ConfigDebugLogger(os.Stdout), 29 | ) 30 | if nil != err { 31 | fmt.Println(err) 32 | os.Exit(1) 33 | } 34 | 35 | // Use an *nrhttprouter.Router in place of an *httprouter.Router. 36 | router := nrhttprouter.New(app) 37 | 38 | router.GET("/", index) 39 | router.GET("/hello/:name", hello) 40 | 41 | http.ListenAndServe(":8000", router) 42 | } 43 | -------------------------------------------------------------------------------- /v3/integrations/nrhttprouter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrhttprouter 2 | 3 | // As of Dec 2019, the httprouter go.mod file uses 1.7: 4 | // https://github.com/julienschmidt/httprouter/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | // v1.3.0 is the earliest version of httprouter using modules. 9 | github.com/julienschmidt/httprouter v1.3.0 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrlambda/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrlambda [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlambda?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlambda) 2 | 3 | Package `nrlambda` adds support for AWS Lambda. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrlambda" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlambda). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrlambda/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrlambda 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | 10 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 11 | ) 12 | 13 | func TestNewConfig(t *testing.T) { 14 | opt := newConfigInternal(func(key string) string { 15 | switch key { 16 | case "NEW_RELIC_ACCOUNT_ID": 17 | return "the-account-id" 18 | case "NEW_RELIC_TRUSTED_ACCOUNT_KEY": 19 | return "the-trust-key" 20 | case "NEW_RELIC_PRIMARY_APPLICATION_ID": 21 | return "the-app-id" 22 | case "NEW_RELIC_APDEX_T": 23 | return "2" 24 | default: 25 | return "" 26 | } 27 | }) 28 | cfg := &newrelic.Config{} 29 | opt(cfg) 30 | if !cfg.ServerlessMode.Enabled { 31 | t.Error(cfg.ServerlessMode.Enabled) 32 | } 33 | if cfg.ServerlessMode.AccountID != "the-account-id" { 34 | t.Error(cfg.ServerlessMode.AccountID) 35 | } 36 | if cfg.ServerlessMode.TrustedAccountKey != "the-trust-key" { 37 | t.Error(cfg.ServerlessMode.TrustedAccountKey) 38 | } 39 | if cfg.ServerlessMode.PrimaryAppID != "the-app-id" { 40 | t.Error(cfg.ServerlessMode.PrimaryAppID) 41 | } 42 | if cfg.ServerlessMode.ApdexThreshold != 2*time.Second { 43 | t.Error(cfg.ServerlessMode.ApdexThreshold) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /v3/integrations/nrlambda/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | "github.com/newrelic/go-agent/v3/integrations/nrlambda" 11 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 12 | ) 13 | 14 | func handler(ctx context.Context) { 15 | // The nrlambda handler instrumentation will add the transaction to the 16 | // context. Access it using newrelic.FromContext to add additional 17 | // instrumentation. 18 | txn := newrelic.FromContext(ctx) 19 | txn.AddAttribute("userLevel", "gold") 20 | txn.Application().RecordCustomEvent("MyEvent", map[string]interface{}{ 21 | "zip": "zap", 22 | }) 23 | 24 | fmt.Println("hello world") 25 | } 26 | 27 | func main() { 28 | // Pass nrlambda.ConfigOption() into newrelic.NewApplication to set 29 | // Lambda specific configuration settings including 30 | // Config.ServerlessMode.Enabled. 31 | app, err := newrelic.NewApplication(nrlambda.ConfigOption()) 32 | if nil != err { 33 | fmt.Println("error creating app (invalid config):", err) 34 | } 35 | // nrlambda.Start should be used in place of lambda.Start. 36 | // nrlambda.StartHandler should be used in place of lambda.StartHandler. 37 | nrlambda.Start(handler, app) 38 | } 39 | -------------------------------------------------------------------------------- /v3/integrations/nrlambda/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrlambda 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/aws/aws-lambda-go v1.41.0 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrlogrus/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrlogrus [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogrus?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogrus) 2 | 3 | Package `nrlogrus` sends go-agent log messages to https://github.com/sirupsen/logrus. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrlogrus" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogrus). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrlogrus/examples/server/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "io" 9 | "net/http" 10 | "os" 11 | 12 | "github.com/newrelic/go-agent/v3/integrations/nrlogrus" 13 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 14 | "github.com/sirupsen/logrus" 15 | ) 16 | 17 | func main() { 18 | logrus.SetLevel(logrus.DebugLevel) 19 | 20 | app, err := newrelic.NewApplication( 21 | newrelic.ConfigAppName("Logrus App"), 22 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 23 | nrlogrus.ConfigStandardLogger(), 24 | ) 25 | 26 | if nil != err { 27 | fmt.Println(err) 28 | os.Exit(1) 29 | } 30 | 31 | http.HandleFunc(newrelic.WrapHandleFunc(app, "/", func(w http.ResponseWriter, r *http.Request) { 32 | io.WriteString(w, "hello world") 33 | })) 34 | 35 | http.ListenAndServe(":8000", nil) 36 | } 37 | -------------------------------------------------------------------------------- /v3/integrations/nrlogrus/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrlogrus 2 | 3 | // As of Dec 2019, the logrus go.mod file uses 1.13: 4 | // https://github.com/sirupsen/logrus/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | github.com/newrelic/go-agent/v3/integrations/logcontext-v2/nrlogrus v1.0.0 10 | // v1.1.0 is required for the Logger.GetLevel method, and is the earliest 11 | // version of logrus using modules. 12 | github.com/sirupsen/logrus v1.8.1 13 | ) 14 | 15 | 16 | replace github.com/newrelic/go-agent/v3 => ../.. 17 | -------------------------------------------------------------------------------- /v3/integrations/nrlogxi/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrlogxi [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogxi?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogxi) 2 | 3 | Package `nrlogxi` supports https://github.com/mgutz/logxi. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrlogxi" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrlogxi). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrlogxi/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrlogxi_test 5 | 6 | import ( 7 | log "github.com/mgutz/logxi/v1" 8 | nrlogxi "github.com/newrelic/go-agent/v3/integrations/nrlogxi" 9 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 10 | ) 11 | 12 | func Example() { 13 | // Create a new logxi logger: 14 | l := log.New("newrelic") 15 | l.SetLevel(log.LevelInfo) 16 | 17 | newrelic.NewApplication( 18 | newrelic.ConfigAppName("Example App"), 19 | newrelic.ConfigLicense("__YOUR_NEWRELIC_LICENSE_KEY__"), 20 | // Use nrlogxi to register the logger with the agent: 21 | nrlogxi.ConfigLogger(l), 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /v3/integrations/nrlogxi/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrlogxi 2 | 3 | // As of Dec 2019, logxi requires 1.3+: 4 | // https://github.com/mgutz/logxi#requirements 5 | go 1.22 6 | 7 | require ( 8 | // 'v1', at commit aebf8a7d67ab, is the only logxi release. 9 | github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrmicro/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrmicro [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmicro?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmicro) 2 | 3 | Package `nrmicro` instruments https://github.com/micro/go-micro. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrmicro" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmicro). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrmicro/example/README.md: -------------------------------------------------------------------------------- 1 | # Example Go Micro apps 2 | In this directory you will find several example Go Micro apps that are instrumented using the New Relic agent. All of the apps assume that your New Relic license key is available as an environment variable named `NEW_RELIC_LICENSE_KEY` 3 | 4 | They can be run the standard way: 5 | * The sample Pub/Sub app: `go run pubsub/main.go` instruments both a publish and a subscribe method 6 | * The sample Server app: `go run server/server.go` instruments a handler method 7 | * The sample Client app: `go run client/client.go` instruments the client. 8 | * Note that in order for this to function, the server app must also be running. 9 | -------------------------------------------------------------------------------- /v3/integrations/nrmicro/example/proto/greeter.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | service Greeter { 7 | rpc Hello(HelloRequest) returns (HelloResponse) {} 8 | } 9 | 10 | message HelloRequest { 11 | string name = 1; 12 | } 13 | 14 | message HelloResponse { 15 | string greeting = 2; 16 | } 17 | -------------------------------------------------------------------------------- /v3/integrations/nrmicro/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrmicro 2 | 3 | // As of Dec 2019, the go-micro go.mod file uses 1.13: 4 | // https://github.com/micro/go-micro/blob/master/go.mod 5 | go 1.22 6 | 7 | toolchain go1.24.2 8 | 9 | require ( 10 | github.com/golang/protobuf v1.5.4 11 | github.com/micro/go-micro v1.8.0 12 | github.com/newrelic/go-agent/v3 v3.39.0 13 | google.golang.org/protobuf v1.36.6 14 | ) 15 | 16 | 17 | replace github.com/newrelic/go-agent/v3 => ../.. 18 | -------------------------------------------------------------------------------- /v3/integrations/nrmongo/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrmongo [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmongo?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmongo) 2 | 3 | Package `nrmongo` instruments https://github.com/mongodb/mongo-go-driver 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrmongo" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmongo). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrmongo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrmongo 2 | 3 | // As of Dec 2019, 1.10 is the mongo-driver requirement: 4 | // https://github.com/mongodb/mongo-go-driver#requirements 5 | go 1.22 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | // mongo-driver does not support modules as of Nov 2019. 10 | go.mongodb.org/mongo-driver v1.10.2 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrmssql/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrmssql [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql) 2 | 3 | Package `nrmssql` instruments github.com/microsoft/go-mssqldb. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrmssql" 7 | ``` 8 | 9 | -------------------------------------------------------------------------------- /v3/integrations/nrmssql/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "fmt" 7 | "os" 8 | "time" 9 | 10 | _ "github.com/newrelic/go-agent/v3/integrations/nrmssql" 11 | "github.com/newrelic/go-agent/v3/newrelic" 12 | ) 13 | 14 | func main() { 15 | // Set up a local ms sql docker 16 | 17 | db, err := sql.Open("nrmssql", "server=localhost;user id=sa;database=master;app name=MyAppName") 18 | if nil != err { 19 | panic(err) 20 | } 21 | 22 | app, err := newrelic.NewApplication( 23 | newrelic.ConfigAppName("MSSQL App"), 24 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 25 | newrelic.ConfigDebugLogger(os.Stdout), 26 | ) 27 | if nil != err { 28 | panic(err) 29 | } 30 | app.WaitForConnection(5 * time.Second) 31 | txn := app.StartTransaction("mssqlQuery") 32 | 33 | ctx := newrelic.NewContext(context.Background(), txn) 34 | row := db.QueryRowContext(ctx, "SELECT count(*) from tables") 35 | var count int 36 | row.Scan(&count) 37 | 38 | txn.End() 39 | app.Shutdown(5 * time.Second) 40 | 41 | fmt.Println("number of tables in information_schema", count) 42 | } 43 | -------------------------------------------------------------------------------- /v3/integrations/nrmssql/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrmssql 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/microsoft/go-mssqldb v0.19.0 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | ) 9 | 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrmysql/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrmysql [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql) 2 | 3 | Package `nrmysql` instruments https://github.com/go-sql-driver/mysql. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrmysql" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrmysql). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrmysql/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "database/sql" 9 | "fmt" 10 | "os" 11 | "time" 12 | 13 | _ "github.com/newrelic/go-agent/v3/integrations/nrmysql" 14 | "github.com/newrelic/go-agent/v3/newrelic" 15 | ) 16 | 17 | func main() { 18 | // Set up a local mysql docker container with: 19 | // docker run -it -p 3306:3306 --net "bridge" -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql 20 | 21 | db, err := sql.Open("nrmysql", "root@/information_schema") 22 | if nil != err { 23 | panic(err) 24 | } 25 | 26 | app, err := newrelic.NewApplication( 27 | newrelic.ConfigAppName("MySQL App"), 28 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 29 | newrelic.ConfigDebugLogger(os.Stdout), 30 | ) 31 | if nil != err { 32 | panic(err) 33 | } 34 | app.WaitForConnection(5 * time.Second) 35 | txn := app.StartTransaction("mysqlQuery") 36 | 37 | ctx := newrelic.NewContext(context.Background(), txn) 38 | row := db.QueryRowContext(ctx, "SELECT count(*) from tables") 39 | var count int 40 | row.Scan(&count) 41 | 42 | txn.End() 43 | app.Shutdown(5 * time.Second) 44 | 45 | fmt.Println("number of tables in information_schema", count) 46 | } 47 | -------------------------------------------------------------------------------- /v3/integrations/nrmysql/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrmysql 2 | 3 | // 1.10 is the Go version in mysql's go.mod 4 | go 1.22 5 | 6 | require ( 7 | // v1.5.0 is the first mysql version to support gomod 8 | github.com/go-sql-driver/mysql v1.6.0 9 | // v3.3.0 includes the new location of ParseQuery 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrnats/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrnats [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrnats?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrnats) 2 | 3 | Package `nrnats` instruments https://github.com/nats-io/nats.go. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrnats" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrnats). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrnats/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrnats_test 5 | 6 | import ( 7 | "fmt" 8 | "time" 9 | 10 | "github.com/nats-io/nats.go" 11 | "github.com/newrelic/go-agent/v3/integrations/nrnats" 12 | "github.com/newrelic/go-agent/v3/newrelic" 13 | ) 14 | 15 | func currentTransaction() *newrelic.Transaction { return nil } 16 | 17 | func ExampleStartPublishSegment() { 18 | nc, _ := nats.Connect(nats.DefaultURL) 19 | txn := currentTransaction() 20 | subject := "testing.subject" 21 | 22 | // Start the Publish segment 23 | seg := nrnats.StartPublishSegment(txn, nc, subject) 24 | err := nc.Publish(subject, []byte("Hello World")) 25 | if nil != err { 26 | panic(err) 27 | } 28 | // Manually end the segment 29 | seg.End() 30 | } 31 | 32 | func ExampleStartPublishSegment_defer() { 33 | nc, _ := nats.Connect(nats.DefaultURL) 34 | txn := currentTransaction() 35 | subject := "testing.subject" 36 | 37 | // Start the Publish segment and defer End till the func returns 38 | defer nrnats.StartPublishSegment(txn, nc, subject).End() 39 | m, err := nc.Request(subject, []byte("request"), time.Second) 40 | if nil != err { 41 | panic(err) 42 | } 43 | fmt.Println("Received reply message:", string(m.Data)) 44 | } 45 | -------------------------------------------------------------------------------- /v3/integrations/nrnats/examples/README.md: -------------------------------------------------------------------------------- 1 | # Example NATS app 2 | In this example app you can find several different ways of instrumenting NATS functions using New Relic. In order to run the app, make sure the following assumptions are correct: 3 | * Your New Relic license key is available as an environment variable named `NEW_RELIC_LICENSE_KEY` 4 | * A NATS server is running locally at the `nats.DefaultURL` 5 | -------------------------------------------------------------------------------- /v3/integrations/nrnats/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrnats 2 | 3 | // As of Jun 2023, 1.19 is the earliest version of Go tested by nats: 4 | // https://github.com/nats-io/nats.go/blob/master/.travis.yml 5 | go 1.22 6 | 7 | toolchain go1.23.4 8 | 9 | require ( 10 | github.com/nats-io/nats-server v1.4.1 11 | github.com/nats-io/nats.go v1.36.0 12 | github.com/newrelic/go-agent/v3 v3.39.0 13 | ) 14 | 15 | 16 | replace github.com/newrelic/go-agent/v3 => ../.. 17 | -------------------------------------------------------------------------------- /v3/integrations/nrnats/test/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/test 2 | 3 | // This module exists to avoid having extra nrnats module dependencies. 4 | go 1.22 5 | 6 | replace github.com/newrelic/go-agent/v3/integrations/nrnats v1.0.0 => ../ 7 | 8 | require ( 9 | github.com/nats-io/nats-server v1.4.1 10 | github.com/nats-io/nats.go v1.17.0 11 | github.com/newrelic/go-agent/v3 v3.39.0 12 | github.com/newrelic/go-agent/v3/integrations/nrnats v1.0.0 13 | ) 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nropenai/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nropenai 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/google/uuid v1.6.0 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/pkoukk/tiktoken-go v0.1.6 9 | github.com/sashabaranov/go-openai v1.20.2 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrpgx [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx) 2 | 3 | Package `nrpgx` instruments https://github.com/jackc/pgx/v4. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrpgx" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx/example/sqlx/go.mod: -------------------------------------------------------------------------------- 1 | // This sqlx example is a separate module to avoid adding sqlx dependency to the 2 | // nrpgx go.mod file. 3 | module github.com/newrelic/go-agent/v3/integrations/nrpgx/example/sqlx 4 | go 1.22 5 | require ( 6 | github.com/jmoiron/sqlx v1.2.0 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/newrelic/go-agent/v3/integrations/nrpgx v0.0.0 9 | ) 10 | replace github.com/newrelic/go-agent/v3/integrations/nrpgx => ../../ 11 | replace github.com/newrelic/go-agent/v3 => ../../../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrpgx 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/jackc/pgx v3.6.2+incompatible 7 | github.com/jackc/pgx/v4 v4.18.2 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | ) 10 | 11 | 12 | replace github.com/newrelic/go-agent/v3 => ../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx5/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrpgx5 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx5?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx5) 2 | 3 | Package `nrpgx5` instruments https://github.com/jackc/pgx/v5. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrpgx5" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpgx5). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx5/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrpgx5 2 | 3 | go 1.22 4 | 5 | toolchain go1.24.2 6 | 7 | require ( 8 | github.com/egon12/pgsnap v0.0.0-20221022154027-2847f0124ed8 9 | github.com/jackc/pgx/v5 v5.5.4 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | github.com/stretchr/testify v1.8.1 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrpgx5/pgsnap_tracer_connect.txt: -------------------------------------------------------------------------------- 1 | F {"Type":"Parse","Name":"stmtcache_8","Query":"INSERT INTO mytable(name) VALUES ($1)","ParameterOIDs":null} 2 | F {"Type":"Describe","ObjectType":"S","Name":"stmtcache_8"} 3 | F {"Type":"Sync"} 4 | B {"Type":"ParseComplete"} 5 | B {"Type":"ParameterDescription","ParameterOIDs":[1043]} 6 | B {"Type":"NoData"} 7 | B {"Type":"ReadyForQuery","TxStatus":"I"} 8 | F {"Type":"Bind","DestinationPortal":"","PreparedStatement":"stmtcache_8","ParameterFormatCodes":[0],"Parameters":[{"text":"myname is"}],"ResultFormatCodes":[]} 9 | F {"Type":"Describe","ObjectType":"P","Name":""} 10 | F {"Type":"Execute","Portal":"","MaxRows":0} 11 | F {"Type":"Sync"} 12 | B {"Type":"BindComplete"} 13 | B {"Type":"NoData"} 14 | B {"Type":"CommandComplete","CommandTag":"INSERT 0 1"} 15 | B {"Type":"ReadyForQuery","TxStatus":"I"} 16 | F {"Type":"Terminate"} 17 | -------------------------------------------------------------------------------- /v3/integrations/nrpkgerrors/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrpkgerrors [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpkgerrors?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpkgerrors) 2 | 3 | Package `nrpkgerrors` introduces support for https://github.com/pkg/errors. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrpkgerrors" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpkgerrors). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrpkgerrors/example/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "time" 10 | 11 | "github.com/newrelic/go-agent/v3/integrations/nrpkgerrors" 12 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 13 | "github.com/pkg/errors" 14 | ) 15 | 16 | type sampleError string 17 | 18 | func (e sampleError) Error() string { 19 | return string(e) 20 | } 21 | 22 | func alpha() error { 23 | return errors.WithStack(sampleError("alpha is the cause")) 24 | } 25 | 26 | func beta() error { 27 | return errors.WithStack(alpha()) 28 | } 29 | 30 | func gamma() error { 31 | return errors.Wrap(beta(), "gamma was involved") 32 | } 33 | 34 | func main() { 35 | app, err := newrelic.NewApplication( 36 | newrelic.ConfigAppName("pkg/errors App"), 37 | newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")), 38 | newrelic.ConfigDebugLogger(os.Stdout), 39 | ) 40 | if nil != err { 41 | fmt.Println(err) 42 | os.Exit(1) 43 | } 44 | 45 | if err := app.WaitForConnection(5 * time.Second); nil != err { 46 | fmt.Println(err) 47 | } 48 | 49 | txn := app.StartTransaction("has-error") 50 | e := gamma() 51 | txn.NoticeError(nrpkgerrors.Wrap(e)) 52 | txn.End() 53 | 54 | app.Shutdown(10 * time.Second) 55 | } 56 | -------------------------------------------------------------------------------- /v3/integrations/nrpkgerrors/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrpkgerrors_test 5 | 6 | import ( 7 | "github.com/newrelic/go-agent/v3/integrations/nrpkgerrors" 8 | newrelic "github.com/newrelic/go-agent/v3/newrelic" 9 | "github.com/pkg/errors" 10 | ) 11 | 12 | type rootError string 13 | 14 | func (e rootError) Error() string { return string(e) } 15 | 16 | func makeRootError() error { 17 | return errors.WithStack(rootError("this is the original error")) 18 | } 19 | 20 | func Example() { 21 | var txn *newrelic.Transaction 22 | e := errors.Wrap(makeRootError(), "extra information") 23 | // Wrap the error to record stack-trace and class type information from 24 | // the error's root cause. Here, "rootError" will be recored as the 25 | // class and top stack-trace frame will be inside makeRootError(). 26 | // Without nrpkgerrors.Wrap, "*errors.withStack" would be recorded as 27 | // the class and the top stack-trace frame would be site of the 28 | // NoticeError call. 29 | txn.NoticeError(nrpkgerrors.Wrap(e)) 30 | } 31 | -------------------------------------------------------------------------------- /v3/integrations/nrpkgerrors/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrpkgerrors 2 | 3 | // As of Dec 2019, 1.11 is the earliest version of Go tested by pkg/errors: 4 | // https://github.com/pkg/errors/blob/master/.travis.yml 5 | go 1.22 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | // v0.8.0 was the last release in 2016, and when 10 | // major development on pkg/errors stopped. 11 | github.com/pkg/errors v0.8.0 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrpq/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrpq [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpq?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpq) 2 | 3 | Package `nrpq` instruments https://github.com/lib/pq. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrpq" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrpq). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrpq/example/sqlx/go.mod: -------------------------------------------------------------------------------- 1 | // This sqlx example is a separate module to avoid adding sqlx dependency to the 2 | // nrpq go.mod file. 3 | module github.com/newrelic/go-agent/v3/integrations/nrpq/example/sqlx 4 | go 1.22 5 | require ( 6 | github.com/jmoiron/sqlx v1.2.0 7 | github.com/lib/pq v1.1.0 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | github.com/newrelic/go-agent/v3/integrations/nrpq v0.0.0 10 | ) 11 | replace github.com/newrelic/go-agent/v3/integrations/nrpq => ../../ 12 | replace github.com/newrelic/go-agent/v3 => ../../../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrpq/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrpq 2 | 3 | go 1.22 4 | 5 | require ( 6 | // NewConnector dsn parsing tests expect v1.1.0 error return behavior. 7 | github.com/lib/pq v1.1.0 8 | // v3.3.0 includes the new location of ParseQuery 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v7/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrredis-v7 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v7?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v7) 2 | 3 | Package `nrredis` instruments `"github.com/go-redis/redis/v7"`. 4 | 5 | ```go 6 | import nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v7" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v7). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v7/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrredis-v7 2 | 3 | // https://github.com/go-redis/redis/blob/master/go.mod 4 | go 1.22 5 | 6 | require ( 7 | github.com/go-redis/redis/v7 v7.0.0-beta.5 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | ) 10 | 11 | 12 | replace github.com/newrelic/go-agent/v3 => ../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v8/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrredis-v8 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v8?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v8) 2 | 3 | Package `nrredis` instruments `"github.com/go-redis/redis/v8"`. 4 | 5 | ```go 6 | import nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v8" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrredis-v8). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v8/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrredis-v8 2 | 3 | // https://github.com/go-redis/redis/blob/master/go.mod 4 | go 1.22 5 | 6 | require ( 7 | github.com/go-redis/redis/v8 v8.4.0 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | ) 10 | 11 | 12 | replace github.com/newrelic/go-agent/v3 => ../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v9/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrredis-v9 [![pkg.go.dev](https://pkg.go.dev/github.com/newrelic/go-agent/v3/integrations/nrredis-v9?status.svg)](https://pkg.go.dev/github.com/newrelic/go-agent/v3/integrations/nrredis-v9) 2 | 3 | Package `nrredis` instruments `"github.com/redis/go-redis/v9"`. 4 | 5 | ```go 6 | import nrredis "github.com/newrelic/go-agent/v3/integrations/nrredis-v9" 7 | ``` 8 | 9 | For more information, see 10 | [pkg.go.dev](https://pkg.go.dev/github.com/newrelic/go-agent/v3/integrations/nrredis-v9). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrredis-v9/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrredis-v9 2 | 3 | // https://github.com/redis/go-redis/blob/a38f75b640398bd709ee46c778a23e80e09d48b5/go.mod#L3 4 | go 1.22 5 | 6 | require ( 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/redis/go-redis/v9 v9.0.2 9 | ) 10 | 11 | 12 | replace github.com/newrelic/go-agent/v3 => ../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrsarama/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrsarama 2 | 3 | go 1.22 4 | 5 | toolchain go1.24.2 6 | 7 | require ( 8 | github.com/Shopify/sarama v1.38.1 9 | github.com/newrelic/go-agent/v3 v3.39.0 10 | github.com/stretchr/testify v1.8.1 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrsecureagent/README.md: -------------------------------------------------------------------------------- 1 | # Renamed 2 | In some early pre-release builds, there was an integration called `nrsecureagent`. 3 | This has now been renamed to `nrsecurityagent`. 4 | In case any documentation directed you to the old name, please use the new name instead and report an issue to correct the outdated reference in the documentation which still has the old name. 5 | -------------------------------------------------------------------------------- /v3/integrations/nrsecurityagent/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrsecurityagent 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/csec-go-agent v1.6.0 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0 9 | gopkg.in/yaml.v2 v2.4.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrslog/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrslog [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrslog?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrslog) 2 | 3 | Package `nrslog` supports `log/slog`. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrslog" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrslog). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrslog/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrslog 2 | 3 | // The new log/slog package in Go 1.21 brings structured logging to the standard library. 4 | go 1.22 5 | 6 | require ( 7 | github.com/newrelic/go-agent/v3 v3.39.0 8 | github.com/stretchr/testify v1.9.0 9 | ) 10 | 11 | replace github.com/newrelic/go-agent/v3 => ../.. 12 | -------------------------------------------------------------------------------- /v3/integrations/nrsnowflake/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrsnowflake [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsnowflake?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsnowflake) 2 | 3 | Package `nrsnowflake` instruments https://github.com/snowflakedb/gosnowflake. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrsnowflake" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsnowflake). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrsnowflake/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrsnowflake 2 | 3 | go 1.22 4 | 5 | toolchain go1.23.2 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | github.com/snowflakedb/gosnowflake v1.14.0 10 | ) 11 | 12 | 13 | replace github.com/newrelic/go-agent/v3 => ../.. 14 | -------------------------------------------------------------------------------- /v3/integrations/nrsqlite3/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrsqlite3 [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsqlite3?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsqlite3) 2 | 3 | Package `nrsqlite3` instruments https://github.com/mattn/go-sqlite3. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrsqlite3" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrsqlite3). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrsqlite3/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrsqlite3 2 | 3 | // As of Dec 2019, 1.9 is the oldest version of Go tested by go-sqlite3: 4 | // https://github.com/mattn/go-sqlite3/blob/master/.travis.yml 5 | go 1.22 6 | 7 | require ( 8 | github.com/mattn/go-sqlite3 v1.0.0 9 | // v3.3.0 includes the new location of ParseQuery 10 | github.com/newrelic/go-agent/v3 v3.39.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrsqlite3/nrsqlite3_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrsqlite3 5 | 6 | import ( 7 | "path/filepath" 8 | "runtime" 9 | "testing" 10 | ) 11 | 12 | func TestGetPortPathOrID(t *testing.T) { 13 | _, here, _, _ := runtime.Caller(0) 14 | currentDir := filepath.Dir(here) 15 | 16 | testcases := []struct { 17 | dsn string 18 | expected string 19 | }{ 20 | {":memory:", ":memory:"}, 21 | {"test.db", filepath.Join(currentDir, "test.db")}, 22 | {"file:/test.db?cache=shared&mode=memory", "/test.db"}, 23 | {"file::memory:", ":memory:"}, 24 | {"", ""}, 25 | } 26 | 27 | for _, test := range testcases { 28 | if actual := getPortPathOrID(test.dsn); actual != test.expected { 29 | t.Errorf(`incorrect port path or id: dsn="%s", actual="%s"`, test.dsn, actual) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /v3/integrations/nrstan/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrstan [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrstan?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrstan) 2 | 3 | Package `nrstan` instruments https://github.com/nats-io/stan.go. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrstan" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrstan). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrstan/examples/README.md: -------------------------------------------------------------------------------- 1 | # Example STAN app 2 | In this example app you can find several different ways of instrumenting NATS Streaming functions using New Relic. In order to run the app, make sure the following assumptions are correct: 3 | * Your New Relic license key is available as an environment variable named `NEW_RELIC_LICENSE_KEY` 4 | * A NATS Streaming Server is running with the cluster id `test-cluster` -------------------------------------------------------------------------------- /v3/integrations/nrstan/examples/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrstan/examples 2 | // This module exists to avoid a dependency on nrnrats. 3 | go 1.22 4 | require ( 5 | github.com/nats-io/stan.go v0.5.0 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/newrelic/go-agent/v3/integrations/nrnats v0.0.0 8 | github.com/newrelic/go-agent/v3/integrations/nrstan v0.0.0 9 | ) 10 | replace github.com/newrelic/go-agent/v3/integrations/nrstan => ../ 11 | replace github.com/newrelic/go-agent/v3/integrations/nrnats => ../../nrnats/ 12 | replace github.com/newrelic/go-agent/v3 => ../../.. 13 | -------------------------------------------------------------------------------- /v3/integrations/nrstan/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrstan 2 | 3 | // As of Dec 2019, 1.11 is the earliest Go version tested by Stan: 4 | // https://github.com/nats-io/stan.go/blob/master/.travis.yml 5 | go 1.22 6 | 7 | toolchain go1.24.2 8 | 9 | require ( 10 | github.com/nats-io/stan.go v0.10.4 11 | github.com/newrelic/go-agent/v3 v3.39.0 12 | ) 13 | 14 | 15 | replace github.com/newrelic/go-agent/v3 => ../.. 16 | -------------------------------------------------------------------------------- /v3/integrations/nrstan/test/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrstan/test 2 | 3 | // This module exists to avoid a dependency on 4 | // github.com/nats-io/nats-streaming-server in nrstan. 5 | go 1.22 6 | 7 | toolchain go1.24.2 8 | 9 | require ( 10 | github.com/nats-io/nats-streaming-server v0.25.6 11 | github.com/nats-io/stan.go v0.10.4 12 | github.com/newrelic/go-agent/v3 v3.39.0 13 | github.com/newrelic/go-agent/v3/integrations/nrstan v0.0.0 14 | ) 15 | 16 | 17 | replace github.com/newrelic/go-agent/v3/integrations/nrstan => ../ 18 | 19 | replace github.com/newrelic/go-agent/v3 => ../../.. 20 | -------------------------------------------------------------------------------- /v3/integrations/nrzap/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrzap [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzap?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzap) 2 | 3 | Package `nrzap` supports https://github.com/uber-go/zap. 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrzap" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzap). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrzap/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrzap 2 | 3 | // As of Dec 2019, zap has 1.13 in their go.mod file: 4 | // https://github.com/uber-go/zap/blob/master/go.mod 5 | go 1.22 6 | 7 | require ( 8 | github.com/newrelic/go-agent/v3 v3.39.0 9 | // v1.12.0 is the earliest version of zap using modules. 10 | go.uber.org/zap v1.12.0 11 | ) 12 | 13 | 14 | replace github.com/newrelic/go-agent/v3 => ../.. 15 | -------------------------------------------------------------------------------- /v3/integrations/nrzerolog/README.md: -------------------------------------------------------------------------------- 1 | # v3/integrations/nrzerolog [![GoDoc](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzerolog?status.svg)](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzerolog) 2 | 3 | Package `nrzerolog` supports https://github.com/rs/zerolog 4 | 5 | ```go 6 | import "github.com/newrelic/go-agent/v3/integrations/nrzerolog" 7 | ``` 8 | 9 | For more information, see 10 | [godocs](https://godoc.org/github.com/newrelic/go-agent/v3/integrations/nrzerolog). 11 | -------------------------------------------------------------------------------- /v3/integrations/nrzerolog/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package nrzerolog_test 5 | 6 | import ( 7 | "os" 8 | 9 | "github.com/newrelic/go-agent/v3/integrations/nrzerolog" 10 | "github.com/newrelic/go-agent/v3/newrelic" 11 | "github.com/rs/zerolog" 12 | ) 13 | 14 | func Example() { 15 | // Create a new zerolog logger: 16 | zl := zerolog.New(os.Stderr) 17 | 18 | newrelic.NewApplication( 19 | newrelic.ConfigAppName("Example App"), 20 | newrelic.ConfigLicense("__YOUR_NEWRELIC_LICENSE_KEY__"), 21 | // Use nrzerolog to register the logger with the agent: 22 | nrzerolog.ConfigLogger(&zl), 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /v3/integrations/nrzerolog/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/newrelic/go-agent/v3/integrations/nrzerolog 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/newrelic/go-agent/v3 v3.39.0 7 | github.com/rs/zerolog v1.28.0 8 | ) 9 | replace github.com/newrelic/go-agent/v3 => ../.. 10 | -------------------------------------------------------------------------------- /v3/internal/cat/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package cat 5 | 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | type errUnexpectedArraySize struct { 11 | label string 12 | expected int 13 | actual int 14 | } 15 | 16 | func (e errUnexpectedArraySize) Error() string { 17 | return fmt.Sprintf("%s: expected %d; got %d", e.label, e.expected, e.actual) 18 | } 19 | -------------------------------------------------------------------------------- /v3/internal/cat/headers.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package cat provides functionality related to the wire format of CAT 5 | // headers. 6 | package cat 7 | 8 | // These header names don't match the spec in terms of their casing, but does 9 | // match what Go will give us from http.CanonicalHeaderKey(). Besides, HTTP 10 | // headers are case insensitive anyway. Rejoice! 11 | const ( 12 | NewRelicIDName = "X-Newrelic-Id" 13 | NewRelicTxnName = "X-Newrelic-Transaction" 14 | NewRelicAppDataName = "X-Newrelic-App-Data" 15 | NewRelicSyntheticsName = "X-Newrelic-Synthetics" 16 | NewRelicSyntheticsInfo = "X-Newrelic-Synthetics-Info" 17 | ) 18 | -------------------------------------------------------------------------------- /v3/internal/cat/id.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package cat 5 | 6 | import ( 7 | "errors" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | // IDHeader represents a decoded cross process ID header (generally encoded as 13 | // a string in the form ACCOUNT#BLOB). 14 | type IDHeader struct { 15 | AccountID int 16 | Blob string 17 | } 18 | 19 | var ( 20 | errInvalidAccountID = errors.New("invalid account ID") 21 | ) 22 | 23 | // NewIDHeader parses the given decoded ID header and creates an IDHeader 24 | // representing it. 25 | func NewIDHeader(in []byte) (*IDHeader, error) { 26 | parts := strings.Split(string(in), "#") 27 | if len(parts) != 2 { 28 | return nil, errUnexpectedArraySize{ 29 | label: "unexpected number of ID elements", 30 | expected: 2, 31 | actual: len(parts), 32 | } 33 | } 34 | 35 | account, err := strconv.Atoi(parts[0]) 36 | if err != nil { 37 | return nil, errInvalidAccountID 38 | } 39 | 40 | return &IDHeader{ 41 | AccountID: account, 42 | Blob: parts[1], 43 | }, nil 44 | } 45 | -------------------------------------------------------------------------------- /v3/internal/cat/path_hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package cat 5 | 6 | import ( 7 | "crypto/md5" 8 | "encoding/binary" 9 | "fmt" 10 | "regexp" 11 | ) 12 | 13 | var pathHashValidator = regexp.MustCompile("^[0-9a-f]{8}$") 14 | 15 | // GeneratePathHash generates a path hash given a referring path hash, 16 | // transaction name, and application name. referringPathHash can be an empty 17 | // string if there was no referring path hash. 18 | func GeneratePathHash(referringPathHash, txnName, appName string) (string, error) { 19 | var rph uint32 20 | if referringPathHash != "" { 21 | if !pathHashValidator.MatchString(referringPathHash) { 22 | // Per the spec, invalid referring path hashes should be treated as "0". 23 | referringPathHash = "0" 24 | } 25 | 26 | if _, err := fmt.Sscanf(referringPathHash, "%x", &rph); err != nil { 27 | fmt.Println(rph) 28 | return "", err 29 | } 30 | rph = (rph << 1) | (rph >> 31) 31 | } 32 | 33 | hashInput := fmt.Sprintf("%s;%s", appName, txnName) 34 | hash := md5.Sum([]byte(hashInput)) 35 | low32 := binary.BigEndian.Uint32(hash[12:]) 36 | 37 | return fmt.Sprintf("%08x", rph^low32), nil 38 | } 39 | -------------------------------------------------------------------------------- /v3/internal/cat/path_hash_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package cat 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/newrelic/go-agent/v3/internal/crossagent" 10 | ) 11 | 12 | func TestGeneratePathHash(t *testing.T) { 13 | var tcs []struct { 14 | Name string 15 | ReferringPathHash string 16 | ApplicationName string 17 | TransactionName string 18 | ExpectedPathHash string 19 | } 20 | 21 | err := crossagent.ReadJSON("cat/path_hashing.json", &tcs) 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | for _, tc := range tcs { 27 | hash, err := GeneratePathHash(tc.ReferringPathHash, tc.TransactionName, tc.ApplicationName) 28 | if err != nil { 29 | t.Errorf("%s: error expected to be nil; got %v", tc.Name, err) 30 | } 31 | if hash != tc.ExpectedPathHash { 32 | t.Errorf("%s: expected %s; got %s", tc.Name, tc.ExpectedPathHash, hash) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /v3/internal/com_newrelic_trace_v1/README.md: -------------------------------------------------------------------------------- 1 | # com_newrelic_trace_v1 2 | 3 | To generate the `v1.pb.go` code, run the following from the top level 4 | `github.com/newrelic/go-agent` package: 5 | 6 | ``` 7 | protoc --go_out=. --go_opt=paths=source_relative \ 8 | --go-grpc_out=. --go-grpc_opt=paths=source_relative \ 9 | v3/internal/com_newrelic_trace_v1/v1.proto 10 | ``` 11 | 12 | Be mindful which version of `protoc-gen-go` and `protoc-gen-go-grpc` you are using. 13 | Upgrade both of these tools to the latest with: 14 | 15 | ``` 16 | go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 17 | go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest 18 | ``` 19 | 20 | ## When you regenerate the file 21 | 22 | Once you have generated the code, you will need to add a build tag to the file: 23 | 24 | ```go 25 | // +build go1.9 26 | ``` 27 | 28 | This is because the gRPC/Protocol Buffer libraries only support Go 1.9 and 29 | above. 30 | -------------------------------------------------------------------------------- /v3/internal/com_newrelic_trace_v1/v1.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | syntax = "proto3"; 5 | 6 | package com.newrelic.trace.v1; 7 | 8 | option go_package = "github.com/newrelic/go-agent/v3/internal/com_newrelic_trace_v1"; 9 | 10 | service IngestService { 11 | // Accepts a stream of Span messages, and returns an irregular stream of 12 | // RecordStatus messages. 13 | rpc RecordSpan(stream Span) returns (stream RecordStatus) {} 14 | 15 | // Accepts a stream of SpanBatch messages, and returns an irregular 16 | // stream of RecordStatus messages. This endpoint can be used to improve 17 | // throughput when Span messages are small 18 | rpc RecordSpanBatch(stream SpanBatch) returns (stream RecordStatus) {} 19 | } 20 | 21 | message SpanBatch { 22 | repeated Span spans = 1; 23 | } 24 | 25 | message Span { 26 | string trace_id = 1; 27 | map intrinsics = 2; 28 | map user_attributes = 3; 29 | map agent_attributes = 4; 30 | } 31 | 32 | message AttributeValue { 33 | oneof value { 34 | string string_value = 1; 35 | bool bool_value = 2; 36 | int64 int_value = 3; 37 | double double_value = 4; 38 | } 39 | } 40 | 41 | message RecordStatus { 42 | uint64 messages_seen = 1; 43 | } 44 | -------------------------------------------------------------------------------- /v3/internal/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | type contextKeyType struct{} 7 | 8 | var ( 9 | // TransactionContextKey is the key used for newrelic.FromContext and 10 | // newrelic.NewContext. 11 | TransactionContextKey = contextKeyType(struct{}{}) 12 | 13 | // GinTransactionContextKey is used as the context key in 14 | // nrgin.Middleware and nrgin.Transaction. Unfortunately, Gin requires 15 | // a string context key. We use two different context keys (and check 16 | // both in nrgin.Transaction and newrelic.FromContext) rather than use a 17 | // single string key because context.WithValue will fail golint if used 18 | // with a string key. 19 | GinTransactionContextKey = "newRelicTransaction" 20 | ) 21 | -------------------------------------------------------------------------------- /v3/internal/crossagent/README.md: -------------------------------------------------------------------------------- 1 | # Cross Agent Tests 2 | 3 | At commit a234030dc659a6e6d2b920bcc0dc7e25beb520ef 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/README.md: -------------------------------------------------------------------------------- 1 | These tests cover parsing of Docker container IDs on Linux hosts out of 2 | `/proc/self/cgroup` (or `/proc//cgroup` more generally). 3 | 4 | The `cases.json` file lists each filename in this directory containing 5 | example `/proc/self/cgroup` content, and the expected Docker container ID that 6 | should be parsed from that file. 7 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-0.9.1.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/ 2 | 10:perf_event:/ 3 | 9:blkio:/ 4 | 8:freezer:/ 5 | 7:devices:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 6 | 6:memory:/ 7 | 5:cpuacct:/ 8 | 4:cpu:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 9 | 3:cpuset:/ 10 | 2:name=systemd:/ -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-1.0.0.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/ 2 | 10:perf_event:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 3 | 9:blkio:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 4 | 8:freezer:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 5 | 7:devices:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 6 | 6:memory:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 7 | 5:cpuacct:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 8 | 4:cpu:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a782 9 | 3:cpuset:/ 10 | 2:name=systemd:/ 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-1.1.2-lxc-driver.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 2 | 10:perf_event:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 3 | 9:blkio:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 4 | 8:freezer:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 5 | 7:name=systemd:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 6 | 6:devices:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 7 | 5:memory:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 8 | 4:cpuacct:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 9 | 3:cpu:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 10 | 2:cpuset:/lxc/cb8c113e5f3cf8332f5231f8154adc429ea910f7c29995372de4f571c55d3159 -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-fs.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/ 2 | 10:perf_event:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 3 | 9:blkio:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 4 | 8:freezer:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 5 | 7:name=systemd:/ 6 | 6:devices:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 7 | 5:memory:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 8 | 4:cpuacct:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 9 | 3:cpu:/docker/2a4f870e24a3b52eb9fe7f3e02858c31855e213e568cfa6c76cb046ffa5b8a28 10 | 2:cpuset:/ -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-systemd.txt: -------------------------------------------------------------------------------- 1 | 10:hugetlb:/ 2 | 9:perf_event:/ 3 | 8:blkio:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope 4 | 7:net_cls:/ 5 | 6:freezer:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope 6 | 5:devices:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope 7 | 4:memory:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope 8 | 3:cpuacct,cpu:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope 9 | 2:cpuset:/ 10 | 1:name=systemd:/system.slice/docker-67f98c9e6188f9c1818672a15dbe46237b6ee7e77f834d40d41c5fb3c2f84a2f.scope -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-1.3.txt: -------------------------------------------------------------------------------- 1 | 9:perf_event:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 2 | 8:blkio:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 3 | 7:net_cls:/ 4 | 6:freezer:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 5 | 5:devices:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 6 | 4:memory:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 7 | 3:cpuacct:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 8 | 2:cpu:/docker/47cbd16b77c50cbf71401c069cd2189f0e659af17d5a2daca3bddf59d8a870b2 9 | 1:cpuset:/ 10 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-custom-prefix.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/ 2 | 10:perf_event:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 3 | 9:blkio:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 4 | 8:freezer:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 5 | 7:devices:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 6 | 6:memory:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 7 | 5:cpuacct:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 8 | 4:cpu:/custom-foobar/e6aaf072b17c345d900987ce04e37031d198b02314f8636df2c0edf6538c08c7 9 | 3:cpuset:/ 10 | 2:name=systemd:/ 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-gcp.txt: -------------------------------------------------------------------------------- 1 | 10:net_prio:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 2 | 9:perf_event:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 3 | 8:blkio:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 4 | 7:net_cls:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 5 | 6:freezer:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 6 | 5:devices:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 7 | 4:memory:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 8 | 3:cpuacct:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 9 | 2:cpu:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 10 | 1:cpuset:/f96c541a87e1376f25461f1386cb60208cea35750eac1e24e11566f078715920 -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/docker-too-long.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/ 2 | 10:perf_event:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 3 | 9:blkio:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 4 | 8:freezer:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 5 | 7:devices:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 6 | 6:memory:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 7 | 5:cpuacct:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 8 | 4:cpu:/docker/3ccfa00432798ff38f85839de1e396f771b4acbe9f4ddea0a761c39b9790a7821 9 | 3:cpuset:/ 10 | 2:name=systemd:/ 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/newrelic/go-agent/ac0e154a1445204debd8e87e182c0d698d2f996b/v3/internal/crossagent/cross_agent_tests/docker_container_id/empty.txt -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/heroku.txt: -------------------------------------------------------------------------------- 1 | 1:hugetlb,perf_event,blkio,freezer,devices,memory,cpuacct,cpu,cpuset:/lxc/b6d196c1-50f2-4949-abdb-5d4909864487 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/invalid-characters.txt: -------------------------------------------------------------------------------- 1 | 9:perf_event:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 2 | 8:blkio:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 3 | 7:net_cls:/ 4 | 6:freezer:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 5 | 5:devices:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 6 | 4:memory:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 7 | 3:cpuacct:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 8 | 2:cpu:/docker/WRONGINCORRECTINVALIDCHARSERRONEOUSBADPHONYBROKEN2TERRIBLENOPE55 9 | 1:cpuset:/ 10 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/invalid-length.txt: -------------------------------------------------------------------------------- 1 | 9:perf_event:/docker/47cbd16b77c5 2 | 8:blkio:/docker/47cbd16b77c5 3 | 7:net_cls:/ 4 | 6:freezer:/docker/47cbd16b77c5 5 | 5:devices:/docker/47cbd16b77c5 6 | 4:memory:/docker/47cbd16b77c5 7 | 3:cpuacct:/docker/47cbd16b77c5 8 | 2:cpu:/docker/47cbd16b77c5 9 | 1:cpuset:/ 10 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/no_cpu_subsystem.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 2 | 10:perf_event:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 3 | 9:blkio:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 4 | 8:freezer:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 5 | 7:devices:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 6 | 6:memory:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 7 | 5:cpuacct:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 8 | 4:cpu:/ 9 | 3:cpuset:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 10 | 2:name=systemd:/docker/f37a7e4d17017e7bf774656b19ca4360c6cdc4951c86700a464101d0d9ce97ee 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/ubuntu-14.04-lxc-container.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/lxc/p1 2 | 10:perf_event:/lxc/p1 3 | 9:blkio:/lxc/p1 4 | 8:freezer:/lxc/p1 5 | 7:devices:/lxc/p1 6 | 6:memory:/lxc/p1 7 | 5:cpuacct:/lxc/p1 8 | 4:cpu:/lxc/p1 9 | 3:cpuset:/lxc/p1 10 | 2:name=systemd:/user/1000.user/1.session -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/ubuntu-14.04-no-container.txt: -------------------------------------------------------------------------------- 1 | 11:hugetlb:/user/1000.user/2.session 2 | 10:perf_event:/user/1000.user/2.session 3 | 9:blkio:/user/1000.user/2.session 4 | 8:freezer:/user/1000.user/2.session 5 | 7:devices:/user/1000.user/2.session 6 | 6:memory:/user/1000.user/2.session 7 | 5:cpuacct:/user/1000.user/2.session 8 | 4:cpu:/user/1000.user/2.session 9 | 3:cpuset:/user/1000.user/2.session 10 | 2:name=systemd:/user/1000.user/2.session -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/docker_container_id/ubuntu-14.10-no-container.txt: -------------------------------------------------------------------------------- 1 | 10:hugetlb:/ 2 | 9:perf_event:/ 3 | 8:blkio:/ 4 | 7:net_cls,net_prio:/ 5 | 6:freezer:/ 6 | 5:devices:/ 7 | 4:memory:/ 8 | 3:cpu,cpuacct:/ 9 | 2:cpuset:/ 10 | 1:name=systemd:/user.slice/user-1000.slice/session-2.scope -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/lambda/README.md: -------------------------------------------------------------------------------- 1 | # event_source_info 2 | 3 | This test fixture is intended to verify that the the agent correctly detects event 4 | types (in languages where type is dynamic) and correctly harvests ARN values. The 5 | fixtures are structured as follows: 6 | 7 | { 8 | "": { 9 | "expected_type": "alb", 10 | "expected_arn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a", 11 | "event": {...} 12 | } 13 | } 14 | 15 | Each fixture is a JSON object with three keys: `expected_type`, `expected_arn`, and `event`. 16 | `event` is an example AWS Lambda invocation event. The other two are values that the agent 17 | should extract from that event, and ought to write test assertions against. 18 | 19 | The top-level `` is provided only for convenience. 20 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL explain plan obfuscation tests 2 | 3 | These tests show how explain plans for PostgreSQL should be obfuscated when 4 | SQL obfuscation is enabled. Obfuscation of explain plans for PostgreSQL is 5 | necessary because they can include portions of the original query that may 6 | contain sensitive data. 7 | 8 | Each test case consists of a set of files with the following extensions: 9 | 10 | * `.query.txt` - the original SQL query that is being explained 11 | * `.explain.txt` - the raw un-obfuscated output from running `EXPLAIN ` 12 | * `.colon_obfuscated.txt` - the desired obfuscated explain output if using the 13 | default, more aggressive obfuscation strategy described [here](https://newrelic.atlassian.net/wiki/display/eng/Obfuscating+PostgreSQL+Explain+plans). 14 | * `.obfuscated.txt` - the desired obfuscated explain output if using a more 15 | accurate, less aggressive obfuscation strategy detailed in this 16 | [Jive thread](https://newrelic.jiveon.com/thread/1851). 17 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/basic_where.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: ? 3 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/basic_where.explain.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = 1234) 3 | Filter: ((title)::text = 'sensitive text'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/basic_where.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = ?) 3 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/basic_where.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.id=1234 AND blogs.title='sensitive text' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/current_date.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..56.60 rows=1 width=5) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/current_date.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..56.60 rows=1 width=5) 2 | Filter: ((j = 'a'::"char") AND (k = ('now'::cstring)::date)) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/current_date.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..56.60 rows=1 width=5) 2 | Filter: ((j = ?::"char") AND (k = (?::cstring)::date)) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/current_date.query.txt: -------------------------------------------------------------------------------- 1 | explain select * from explain_plan_test_4 where j = 'abcd' and k = current_date 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/date.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..39.12 rows=12 width=5) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/date.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..39.12 rows=12 width=5) 2 | Filter: (k = '2001-09-28'::date) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/date.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_4 (cost=0.00..39.12 rows=12 width=5) 2 | Filter: (k = ?::date) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/date.query.txt: -------------------------------------------------------------------------------- 1 | explain select * from explain_plan_test_4 where k = date '2001-09-28'" 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..1.01 rows=1 width=540) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..1.01 rows=1 width=540) 2 | Filter: ((title)::text = '\x08\x0C 3 | \r '::text) 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..1.01 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_newline.query.txt: -------------------------------------------------------------------------------- 1 | select * from blogs where title = E'\x08\x0c\n\r\t' 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..24.50 rows=6 width=40) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..24.50 rows=6 width=40) 2 | Filter: (c = 'three''three'::text) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..24.50 rows=6 width=40) 2 | Filter: (c = ?::text) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/embedded_quote.query.txt: -------------------------------------------------------------------------------- 1 | explain select * from explain_plan_test_1 where c = 'three''three' 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/floating_point.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..27.40 rows=6 width=40) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/floating_point.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..27.40 rows=6 width=40) 2 | Filter: ((a)::numeric = 10000000000::numeric) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/floating_point.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on explain_plan_test_1 (cost=0.00..27.40 rows=6 width=40) 2 | Filter: ((a)::numeric = ?::numeric) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/floating_point.query.txt: -------------------------------------------------------------------------------- 1 | explain select * from explain_plan_test_1 where a = 1e10 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Hash Join (cost=12.93..26.33 rows=130 width=1113) 2 | Hash Cond: ? 3 | -> Seq Scan on blogs (cost=0.00..11.40 rows=140 width=540) 4 | -> Hash (cost=11.30..11.30 rows=130 width=573) 5 | -> Seq Scan on posts (cost=0.00..11.30 rows=130 width=573) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.explain.txt: -------------------------------------------------------------------------------- 1 | Hash Join (cost=12.93..26.33 rows=130 width=1113) 2 | Hash Cond: (pg_catalog.concat(blogs.title, '-suffix') = (posts.title)::text) 3 | -> Seq Scan on blogs (cost=0.00..11.40 rows=140 width=540) 4 | -> Hash (cost=11.30..11.30 rows=130 width=573) 5 | -> Seq Scan on posts (cost=0.00..11.30 rows=130 width=573) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Hash Join (cost=12.93..26.33 rows=130 width=1113) 2 | Hash Cond: (pg_catalog.concat(blogs.title, ?) = (posts.title)::text) 3 | -> Seq Scan on blogs (cost=0.00..11.40 rows=140 width=540) 4 | -> Hash (cost=11.30..11.30 rows=130 width=573) 5 | -> Seq Scan on posts (cost=0.00..11.30 rows=130 width=573) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/function_with_strings.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs JOIN posts ON posts.title=CONCAT(blogs.title, '-suffix') -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on "explain_plan_test'_3" (cost=0.00..24.50 rows=6 width=40) 2 | Filter: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on "explain_plan_test'_3" (cost=0.00..24.50 rows=6 width=40) 2 | Filter: (i = '"abcd"'::text) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on "explain_plan_test'_3" (cost=0.00..24.50 rows=6 width=40) 2 | Filter: (i = ?::text) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/quote_in_table_name.query.txt: -------------------------------------------------------------------------------- 1 | explain select * from "explain_plan_test'_3" where i = '"abcd"' 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/subplan.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Insert on explain_plan_test_1 (cost=24.50..49.00 rows=580 width=40) 2 | -> Seq Scan on explain_plan_test_2 (cost=24.50..49.00 rows=580 width=40) 3 | Filter: ? 4 | SubPlan 1 5 | -> Seq Scan on explain_plan_test_1 (cost=0.00..21.60 rows=1160 width=4) 6 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/subplan.explain.txt: -------------------------------------------------------------------------------- 1 | Insert on explain_plan_test_1 (cost=24.50..49.00 rows=580 width=40) 2 | -> Seq Scan on explain_plan_test_2 (cost=24.50..49.00 rows=580 width=40) 3 | Filter: (NOT (hashed SubPlan 1)) 4 | SubPlan 1 5 | -> Seq Scan on explain_plan_test_1 (cost=0.00..21.60 rows=1160 width=4) 6 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/subplan.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Insert on explain_plan_test_1 (cost=24.50..49.00 rows=580 width=40) 2 | -> Seq Scan on explain_plan_test_2 (cost=24.50..49.00 rows=580 width=40) 3 | Filter: (NOT (hashed SubPlan 1)) 4 | SubPlan 1 5 | -> Seq Scan on explain_plan_test_1 (cost=0.00..21.60 rows=1160 width=4) 6 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/subplan.query.txt: -------------------------------------------------------------------------------- 1 | explain insert into explain_plan_test_1 select * from explain_plan_test_2 where explain_plan_test_2.d not in (select a from explain_plan_test_1) 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: ? 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.explain.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = 1234) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = ?) 3 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_integer.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.id=1234 2 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = '][^|)/('::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_regex_chars.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title='][^|)/(' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: ? 3 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.explain.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = 15402) 3 | Filter: ((title)::text = 'logs'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Index Scan using blogs_pkey on blogs (cost=0.00..8.27 rows=1 width=540) 2 | Index Cond: (id = ?) 3 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/where_with_substring.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.id=15402 AND blogs.title='logs' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'foo''bar'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case1.query.txt: -------------------------------------------------------------------------------- 1 | EXPLAIN SELECT * FROM blogs WHERE blogs.title=E'foo\'bar' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = '\x08\x0C 3 | \r '::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case2.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=E'\b\f\n\r\t' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = '\x01\x079'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case3.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=E'\1\7\9' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'foo''bar'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case4.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title='foo\'bar' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'U'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case5.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=E'\x55' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'data'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case6.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=E'd\u0061t\U00000061' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'data'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case7.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=U&'d\0061t\+000061' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'слон'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case8.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=U&'\0441\043B\043E\043D' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.colon_obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ? -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.explain.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = 'data'::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.obfuscated.txt: -------------------------------------------------------------------------------- 1 | Seq Scan on blogs (cost=0.00..11.75 rows=1 width=540) 2 | Filter: ((title)::text = ?::text) -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/postgres_explain_obfuscation/with_escape_case9.query.txt: -------------------------------------------------------------------------------- 1 | SELECT * FROM blogs WHERE blogs.title=U&'d!0061t!+000061' UESCAPE '!' -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/1pack_1core_1logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : AMD Duron(tm) processor 3 | cache size : 64 KB 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/1pack_1core_2logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : Intel(R) Pentium(R) 4 CPU 2.80GHz 3 | cache size : 1024 KB 4 | physical id : 0 5 | siblings : 2 6 | core id : 0 7 | cpu cores : 1 8 | processor : 1 9 | model name : Intel(R) Pentium(R) 4 CPU 2.80GHz 10 | cache size : 1024 KB 11 | physical id : 0 12 | siblings : 2 13 | core id : 0 14 | cpu cores : 1 15 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/1pack_2core_2logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : Intel(R) Pentium(R) D CPU 3.00GHz 3 | cache size : 2048 KB 4 | physical id : 0 5 | siblings : 2 6 | core id : 0 7 | cpu cores : 2 8 | processor : 1 9 | model name : Intel(R) Pentium(R) D CPU 3.00GHz 10 | cache size : 2048 KB 11 | physical id : 0 12 | siblings : 2 13 | core id : 1 14 | cpu cores : 2 15 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/1pack_4core_4logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : Intel(R) Xeon(R) CPU E5410 @ 2.33GHz 3 | cache size : 6144 KB 4 | physical id : 0 5 | siblings : 4 6 | core id : 0 7 | cpu cores : 4 8 | processor : 1 9 | model name : Intel(R) Xeon(R) CPU E5410 @ 2.33GHz 10 | cache size : 6144 KB 11 | physical id : 0 12 | siblings : 4 13 | core id : 1 14 | cpu cores : 4 15 | processor : 2 16 | model name : Intel(R) Xeon(R) CPU E5410 @ 2.33GHz 17 | cache size : 6144 KB 18 | physical id : 0 19 | siblings : 4 20 | core id : 2 21 | cpu cores : 4 22 | processor : 3 23 | model name : Intel(R) Xeon(R) CPU E5410 @ 2.33GHz 24 | cache size : 6144 KB 25 | physical id : 0 26 | siblings : 4 27 | core id : 3 28 | cpu cores : 4 29 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/2pack_2core_4logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : Intel(R) Xeon(TM) CPU 3.60GHz 3 | cache size : 1024 KB 4 | physical id : 0 5 | siblings : 2 6 | core id : 0 7 | cpu cores : 1 8 | processor : 1 9 | model name : Intel(R) Xeon(TM) CPU 3.60GHz 10 | cache size : 1024 KB 11 | physical id : 3 12 | siblings : 2 13 | core id : 0 14 | cpu cores : 1 15 | processor : 2 16 | model name : Intel(R) Xeon(TM) CPU 3.60GHz 17 | cache size : 1024 KB 18 | physical id : 0 19 | siblings : 2 20 | core id : 0 21 | cpu cores : 1 22 | processor : 3 23 | model name : Intel(R) Xeon(TM) CPU 3.60GHz 24 | cache size : 1024 KB 25 | physical id : 3 26 | siblings : 2 27 | core id : 0 28 | cpu cores : 1 29 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/2pack_4core_4logical.txt: -------------------------------------------------------------------------------- 1 | processor : 0 2 | model name : Intel(R) Xeon(R) CPU 5160 @ 3.00GHz 3 | cache size : 4096 KB 4 | physical id : 0 5 | siblings : 2 6 | core id : 0 7 | cpu cores : 2 8 | processor : 1 9 | model name : Intel(R) Xeon(R) CPU 5160 @ 3.00GHz 10 | cache size : 4096 KB 11 | physical id : 0 12 | siblings : 2 13 | core id : 1 14 | cpu cores : 2 15 | processor : 2 16 | model name : Intel(R) Xeon(R) CPU 5160 @ 3.00GHz 17 | cache size : 4096 KB 18 | physical id : 3 19 | siblings : 2 20 | core id : 0 21 | cpu cores : 2 22 | processor : 3 23 | model name : Intel(R) Xeon(R) CPU 5160 @ 3.00GHz 24 | cache size : 4096 KB 25 | physical id : 3 26 | siblings : 2 27 | core id : 1 28 | cpu cores : 2 29 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_cpuinfo/malformed_file.txt: -------------------------------------------------------------------------------- 1 | This is a random text file that does NOT adhere to the /proc/cpuinfo format. 2 | xxxYYYZZz 3 | 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/proc_meminfo/README.md: -------------------------------------------------------------------------------- 1 | These tests are for determining the physical memory from the data returned by 2 | /proc/meminfo on Linux hosts. The total physical memory of the linux system is 3 | reported as part of the environment values. The key used by the Python agent 4 | is 'Total Physical Memory (MB)'. 5 | 6 | The names of all test files should be of the form `meminfo_nnnnMB.txt`. The 7 | value `nnnn` in the filename is the physical memory of that system in MB. 8 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_footer_insertion_location/close-body-in-comment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Comment contains a close body tag 5 | 6 | 7 |

The quick brown fox jumps over the lazy dog.

8 | 9 | EXPECTED_RUM_FOOTER_LOCATION 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_footer_insertion_location/dynamic-iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dynamic iframe Generation 5 | 6 | 7 |

The quick brown fox jumps over the lazy dog.

8 | 11 | 18 | EXPECTED_RUM_FOOTER_LOCATION 19 | 20 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/basic.html: -------------------------------------------------------------------------------- 1 | 2 | EXPECTED_RUM_LOADER_LOCATION 3 | im a title 4 | 5 | 8 | 9 | im some body text 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/body_with_attributes.html: -------------------------------------------------------------------------------- 1 | EXPECTED_RUM_LOADER_LOCATION 2 | This isn't great HTML but it's what we've got. 3 | 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/charset_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | 8 | EXPECTED_RUM_LOADER_LOCATION 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/charset_tag_after_x_ua_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | EXPECTED_RUM_LOADER_LOCATION 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/charset_tag_before_x_ua_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | EXPECTED_RUM_LOADER_LOCATION 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/charset_tag_with_spaces.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | 8 | EXPECTED_RUM_LOADER_LOCATION 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/comments1.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 15 | 16 | 19 | OPT® 20 | 21 | 22 | Cribbed from the Java agent 23 | 24 | 25 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/comments2.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 15 | 16 | 19 | OPT® 20 | 21 | 22 | Cribbed from the Java agent 23 | 24 | 25 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | 8 | EXPECTED_RUM_LOADER_LOCATION 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag_after_x_ua_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | EXPECTED_RUM_LOADER_LOCATION 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/content_type_charset_tag_before_x_ua_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | 5 | EXPECTED_RUM_LOADER_LOCATION 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes1.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 15 | 16 | 19 | OPT® 20 | 21 | 22 | 23 | 24 | 25 | Cribbed from the Java agent 26 | 27 | 28 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes2.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 15 | 16 | 19 | OPT® 20 | 21 | 22 | Cribbed from the Java agent 23 | 24 | 25 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/gt_in_quotes_mismatch.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | ication" content="xxxx" /> 8 | 9 | 11 | 15 | 16 | 19 | OPT® 20 | 21 | 22 | Cribbed from the Java agent 23 | 24 | 25 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/gt_in_single_quotes1.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 15 | 16 | 19 | 20 | OPT® 21 | 22 | 23 | Cribbed from the Java agent 24 | 25 | 26 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/gt_in_single_quotes_mismatch.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | .01' content='yyyy\' /> 9 | 11 | 15 | 16 | 19 | 20 | OPT® 21 | 22 | 23 | Cribbed from the Java agent 24 | 25 | 26 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/head_with_attributes.html: -------------------------------------------------------------------------------- 1 | 2 | EXPECTED_RUM_LOADER_LOCATION 3 | im a title 4 | 5 | 8 | 9 | im some body text 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/incomplete_non_meta_tags.html: -------------------------------------------------------------------------------- 1 | 2 | EXPECTED_RUM_LOADER_LOCATION 3 | 4 | 2 | 3 | EXPECTED_RUM_LOADER_LOCATION 4 | Cribbed from the Java agent 5 | 6 | 7 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/no_header.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | EXPECTED_RUM_LOADER_LOCATION 5 | Cribbed from the Java agent 6 | 7 | 8 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/no_html_and_no_header.html: -------------------------------------------------------------------------------- 1 | EXPECTED_RUM_LOADER_LOCATION 2 | This isn't great HTML but it's what we've got. 3 | 4 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/no_start_header.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | EXPECTED_RUM_LOADER_LOCATION 7 | Cribbed from the Java agent 8 | 9 | 10 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/script1.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 6 | Castor 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/script2.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | EXPECTED_RUM_LOADER_LOCATION 5 | Castor 6 | 7 | 8 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 8 | 9 | im some body text 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiple_tags.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 6 | 9 | 10 | 11 | im some body text 12 | 13 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_spaces_around_equals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 8 | 9 | im some body text 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_with_others.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 6 | 9 | 10 | im some body text 11 | 12 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_with_spaces.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | im a title 4 | EXPECTED_RUM_LOADER_LOCATION 5 | 8 | 9 | im some body text 10 | 11 | -------------------------------------------------------------------------------- /v3/internal/crossagent/cross_agent_tests/utilization_vendor_specific/README.md: -------------------------------------------------------------------------------- 1 | # Vendor Specific Utilization Tests 2 | 3 | The Utilization tests ensure that the appropriate information is being gathered for pricing for a particular cloud vendor. It is centered around ensuring that the JSON generated by all agents is correct. Each JSON block is a test case, with potentially the following fields: 4 | 5 | - `testname`: The name of the test. 6 | - `uri`: The API endpoint for the cloud vendor. This contains a response indicating what the expected return from the API is for a given test. 7 | - `expected_vendors_hash`: The vendor hash that should be generated by the agent based on the uri response. 8 | - `expected_metrics`: Supportability metrics that are either expected or unexpected in a given case. If the `call_count` is 0 it should be asserted that the Supportability metric was not sent. 9 | 10 | As of [Metadata version 3](https://source.datanerd.us/agents/agent-specs/blob/c78cddeaa5fa23dce892b8c6da95b9f900636c35/Utilization.md) specs have been added for Azure, Google Cloud Platform, and Pivotal Cloud Foundry in addition to updates for AWS. -------------------------------------------------------------------------------- /v3/internal/limits.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | const ( 7 | // app behavior 8 | 9 | // DefaultConfigurableEventHarvestMs is the period for custom, error, 10 | // and transaction events if the connect response's 11 | // "event_harvest_config.report_period_ms" is missing or invalid. 12 | DefaultConfigurableEventHarvestMs = 60 * 1000 13 | // MaxPayloadSizeInBytes specifies the maximum payload size in bytes that 14 | // should be sent to any endpoint 15 | MaxPayloadSizeInBytes = 1000 * 1000 16 | // MaxCustomEvents is the maximum number of Transaction Events that can be captured 17 | // per 60-second harvest cycle 18 | MaxCustomEvents = 30 * 1000 19 | // MaxLogEvents is the maximum number of Log Events that can be captured per 20 | // 60-second harvest cycle 21 | MaxLogEvents = 10 * 1000 22 | // MaxTxnEvents is the maximum number of Transaction Events that can be captured 23 | // per 60-second harvest cycle 24 | MaxTxnEvents = 10 * 1000 25 | // MaxErrorEvents is the maximum number of Error Events that can be captured 26 | // per 60-second harvest cycle 27 | MaxErrorEvents = 100 28 | // MaxSpanEvents is the maximum number of Spans Events that can be captured 29 | // per 60-second harvest cycle 30 | MaxSpanEvents = 2000 31 | ) 32 | -------------------------------------------------------------------------------- /v3/internal/logcontext/publicConstants.go: -------------------------------------------------------------------------------- 1 | package logcontext 2 | 3 | // Exported Constants for log decorators 4 | const ( 5 | // LogSeverityFieldName is the name of the log level field in New Relic logging JSON 6 | LogSeverityFieldName = "level" 7 | 8 | // LogMessageFieldName is the name of the log message field in New Relic logging JSON 9 | LogMessageFieldName = "message" 10 | 11 | // LogTimestampFieldName is the name of the timestamp field in New Relic logging JSON 12 | LogTimestampFieldName = "timestamp" 13 | 14 | // LogSpanIDFieldName is the name of the span ID field in the New Relic logging JSON 15 | LogSpanIDFieldName = "span.id" 16 | 17 | // LogTraceIDFieldName is the name of the trace ID field in the New Relic logging JSON 18 | LogTraceIDFieldName = "trace.id" 19 | 20 | // LogSeverityUnknown is the value the log severity should be set to if no log severity is known 21 | LogSeverityUnknown = "UNKNOWN" 22 | 23 | // number of bytes expected to be needed for the average log message 24 | AverageLogSizeEstimate = 400 25 | ) 26 | -------------------------------------------------------------------------------- /v3/internal/stacktracetest/stacktracetest.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package stacktracetest helps test stack trace behavior. 5 | package stacktracetest 6 | 7 | // TopStackFrame is a function should will appear in the stacktrace. 8 | func TopStackFrame(generateStacktrace func() []byte) []byte { 9 | return generateStacktrace() 10 | } 11 | 12 | // CountedCall is a function that allows you to generate a stack trace with this function being called a particular 13 | // number of times. The parameter f should be a function that returns a StackTrace (but it is referred to as []uintptr 14 | // in order to not create a circular dependency on the internal package) 15 | func CountedCall(i int, f func() []uintptr) []uintptr { 16 | if i > 0 { 17 | return CountedCall(i-1, f) 18 | } 19 | return f() 20 | } 21 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "errors" 8 | ) 9 | 10 | var ( 11 | // ErrFeatureUnsupported indicates unsupported platform. 12 | ErrFeatureUnsupported = errors.New("That feature is not supported on this platform") 13 | ) 14 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/hostname.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | // Hostname returns the host name. 7 | func Hostname() (string, error) { 8 | return getHostname() 9 | } 10 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/hostname_generic.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !linux 5 | 6 | package sysinfo 7 | 8 | import "os" 9 | 10 | func getHostname() (string, error) { 11 | return os.Hostname() 12 | } 13 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "bufio" 8 | "errors" 9 | "io" 10 | "regexp" 11 | "strconv" 12 | ) 13 | 14 | // BytesToMebibytes converts bytes into mebibytes. 15 | func BytesToMebibytes(bts uint64) uint64 { 16 | return bts / ((uint64)(1024 * 1024)) 17 | } 18 | 19 | var ( 20 | meminfoRe = regexp.MustCompile(`^MemTotal:\s+([0-9]+)\s+[kK]B$`) 21 | errMemTotalNotFound = errors.New("supported MemTotal not found in /proc/meminfo") 22 | ) 23 | 24 | // parseProcMeminfo is used to parse Linux's "/proc/meminfo". It is located 25 | // here so that the relevant cross agent tests will be run on all platforms. 26 | func parseProcMeminfo(f io.Reader) (uint64, error) { 27 | scanner := bufio.NewScanner(f) 28 | for scanner.Scan() { 29 | if m := meminfoRe.FindSubmatch(scanner.Bytes()); m != nil { 30 | kb, err := strconv.ParseUint(string(m[1]), 10, 64) 31 | if err != nil { 32 | return 0, err 33 | } 34 | return kb * 1024, nil 35 | } 36 | } 37 | 38 | err := scanner.Err() 39 | if err == nil { 40 | err = errMemTotalNotFound 41 | } 42 | return 0, err 43 | } 44 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | // PhysicalMemoryBytes returns the total amount of host memory. 12 | func PhysicalMemoryBytes() (uint64, error) { 13 | mib := []int32{6 /* CTL_HW */, 24 /* HW_MEMSIZE */} 14 | 15 | buf := make([]byte, 8) 16 | bufLen := uintptr(8) 17 | 18 | _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, 19 | uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), 20 | uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)), 21 | uintptr(0), uintptr(0)) 22 | 23 | if e1 != 0 { 24 | return 0, e1 25 | } 26 | 27 | if bufLen != 8 { 28 | return 0, syscall.EIO 29 | } 30 | 31 | return *(*uint64)(unsafe.Pointer(&buf[0])), nil 32 | } 33 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "errors" 8 | "os/exec" 9 | "regexp" 10 | "strconv" 11 | "testing" 12 | ) 13 | 14 | var re = regexp.MustCompile(`hw\.memsize:\s*(\d+)`) 15 | 16 | func darwinSysctlMemoryBytes() (uint64, error) { 17 | out, err := exec.Command("/usr/sbin/sysctl", "hw.memsize").Output() 18 | if err != nil { 19 | return 0, err 20 | } 21 | 22 | match := re.FindSubmatch(out) 23 | if match == nil { 24 | return 0, errors.New("memory size not found in sysctl output") 25 | } 26 | 27 | bts, err := strconv.ParseUint(string(match[1]), 10, 64) 28 | if err != nil { 29 | return 0, err 30 | } 31 | 32 | return bts, nil 33 | } 34 | 35 | func TestPhysicalMemoryBytes(t *testing.T) { 36 | mem, err := PhysicalMemoryBytes() 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | 41 | mem2, err := darwinSysctlMemoryBytes() 42 | if nil != err { 43 | t.Fatal(err) 44 | } 45 | 46 | if mem != mem2 { 47 | t.Error(mem, mem2) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_freebsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | // PhysicalMemoryBytes returns the total amount of host memory. 12 | func PhysicalMemoryBytes() (uint64, error) { 13 | mib := []int32{6 /* CTL_HW */, 5 /* HW_PHYSMEM */} 14 | 15 | buf := make([]byte, 8) 16 | bufLen := uintptr(8) 17 | 18 | _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, 19 | uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), 20 | uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)), 21 | uintptr(0), uintptr(0)) 22 | 23 | if e1 != 0 { 24 | return 0, e1 25 | } 26 | 27 | switch bufLen { 28 | case 4: 29 | return uint64(*(*uint32)(unsafe.Pointer(&buf[0]))), nil 30 | case 8: 31 | return *(*uint64)(unsafe.Pointer(&buf[0])), nil 32 | default: 33 | return 0, syscall.EIO 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_freebsd_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "errors" 8 | "os/exec" 9 | "regexp" 10 | "strconv" 11 | "testing" 12 | ) 13 | 14 | var re = regexp.MustCompile(`hw\.physmem:\s*(\d+)`) 15 | 16 | func freebsdSysctlMemoryBytes() (uint64, error) { 17 | out, err := exec.Command("/sbin/sysctl", "hw.physmem").Output() 18 | if err != nil { 19 | return 0, err 20 | } 21 | 22 | match := re.FindSubmatch(out) 23 | if match == nil { 24 | return 0, errors.New("memory size not found in sysctl output") 25 | } 26 | 27 | bts, err := strconv.ParseUint(string(match[1]), 10, 64) 28 | if err != nil { 29 | return 0, err 30 | } 31 | 32 | return bts, nil 33 | } 34 | 35 | func TestPhysicalMemoryBytes(t *testing.T) { 36 | mem, err := PhysicalMemoryBytes() 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | 41 | mem2, err := freebsdSysctlMemoryBytes() 42 | if nil != err { 43 | t.Fatal(err) 44 | } 45 | 46 | if mem != mem2 { 47 | t.Error(mem, mem2) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_js.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import "errors" 7 | 8 | // PhysicalMemoryBytes returns the total amount of host memory. 9 | func PhysicalMemoryBytes() (uint64, error) { 10 | return 0, errors.New("not supported on GOOS=js") 11 | } 12 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import "os" 7 | 8 | // PhysicalMemoryBytes returns the total amount of host memory. 9 | func PhysicalMemoryBytes() (uint64, error) { 10 | f, err := os.Open("/proc/meminfo") 11 | if err != nil { 12 | return 0, err 13 | } 14 | defer f.Close() 15 | 16 | return parseProcMeminfo(f) 17 | } 18 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_openbsd_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | // PhysicalMemoryBytes returns the total amount of host memory. 12 | func PhysicalMemoryBytes() (uint64, error) { 13 | mib := []int32{6 /* CTL_HW */, 19 /* HW_PHYSMEM64 */} 14 | 15 | buf := make([]byte, 8) 16 | bufLen := uintptr(8) 17 | 18 | _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, 19 | uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), 20 | uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)), 21 | uintptr(0), uintptr(0)) 22 | 23 | if e1 != 0 { 24 | return 0, e1 25 | } 26 | 27 | switch bufLen { 28 | case 4: 29 | return uint64(*(*uint32)(unsafe.Pointer(&buf[0]))), nil 30 | case 8: 31 | return *(*uint64)(unsafe.Pointer(&buf[0])), nil 32 | default: 33 | return 0, syscall.EIO 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_openbsd_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "errors" 8 | "os/exec" 9 | "regexp" 10 | "strconv" 11 | "testing" 12 | ) 13 | 14 | var re = regexp.MustCompile(`hw\.physmem=(\d+)`) 15 | 16 | func openbsdSysctlMemoryBytes() (uint64, error) { 17 | out, err := exec.Command("/sbin/sysctl", "hw.physmem").Output() 18 | if err != nil { 19 | return 0, err 20 | } 21 | 22 | match := re.FindSubmatch(out) 23 | if match == nil { 24 | return 0, errors.New("memory size not found in sysctl output") 25 | } 26 | 27 | bts, err := strconv.ParseUint(string(match[1]), 10, 64) 28 | if err != nil { 29 | return 0, err 30 | } 31 | 32 | return bts, nil 33 | } 34 | 35 | func TestPhysicalMemoryBytes(t *testing.T) { 36 | mem, err := PhysicalMemoryBytes() 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | 41 | mem2, err := openbsdSysctlMemoryBytes() 42 | if nil != err { 43 | t.Fatal(err) 44 | } 45 | 46 | if mem != mem2 { 47 | t.Errorf("Expected %d, got %d\n", mem2, mem) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | /* 7 | #include 8 | */ 9 | import "C" 10 | 11 | // PhysicalMemoryBytes returns the total amount of host memory. 12 | func PhysicalMemoryBytes() (uint64, error) { 13 | // The function we're calling on Solaris is 14 | // long sysconf(int name); 15 | var pages C.long 16 | var pagesizeBytes C.long 17 | var err error 18 | 19 | pagesizeBytes, err = C.sysconf(C._SC_PAGE_SIZE) 20 | if pagesizeBytes < 1 { 21 | return 0, err 22 | } 23 | pages, err = C.sysconf(C._SC_PHYS_PAGES) 24 | if pages < 1 { 25 | return 0, err 26 | } 27 | 28 | return uint64(pages) * uint64(pagesizeBytes), nil 29 | } 30 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "os" 8 | "regexp" 9 | "strconv" 10 | "testing" 11 | 12 | "github.com/newrelic/go-agent/v3/internal/crossagent" 13 | ) 14 | 15 | func TestMemTotal(t *testing.T) { 16 | var fileRe = regexp.MustCompile(`meminfo_([0-9]+)MB.txt$`) 17 | var ignoreFile = regexp.MustCompile(`README\.md$`) 18 | 19 | testCases, err := crossagent.ReadDir("proc_meminfo") 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | 24 | for _, testFile := range testCases { 25 | if ignoreFile.MatchString(testFile) { 26 | continue 27 | } 28 | 29 | matches := fileRe.FindStringSubmatch(testFile) 30 | 31 | if matches == nil || len(matches) < 2 { 32 | t.Error(testFile, matches) 33 | continue 34 | } 35 | 36 | expect, err := strconv.ParseUint(matches[1], 10, 64) 37 | if err != nil { 38 | t.Error(err) 39 | continue 40 | } 41 | 42 | input, err := os.Open(testFile) 43 | if err != nil { 44 | t.Error(err) 45 | continue 46 | } 47 | bts, err := parseProcMeminfo(input) 48 | input.Close() 49 | mib := BytesToMebibytes(bts) 50 | if err != nil { 51 | t.Error(err) 52 | } else if mib != expect { 53 | t.Error(bts, expect) 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/memtotal_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | // PhysicalMemoryBytes returns the total amount of host memory. 12 | func PhysicalMemoryBytes() (uint64, error) { 13 | // https://msdn.microsoft.com/en-us/library/windows/desktop/cc300158(v=vs.85).aspx 14 | // http://stackoverflow.com/questions/30743070/query-total-physical-memory-in-windows-with-golang 15 | mod := syscall.NewLazyDLL("kernel32.dll") 16 | proc := mod.NewProc("GetPhysicallyInstalledSystemMemory") 17 | var memkb uint64 18 | 19 | ret, _, err := proc.Call(uintptr(unsafe.Pointer(&memkb))) 20 | // return value TRUE(1) succeeds, FAILED(0) fails 21 | if ret != 1 { 22 | return 0, err 23 | } 24 | 25 | return memkb * 1024, nil 26 | } 27 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/usage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "time" 8 | ) 9 | 10 | // Usage contains process process times. 11 | type Usage struct { 12 | System time.Duration 13 | User time.Duration 14 | } 15 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/usage_js.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import "errors" 7 | 8 | // GetUsage gathers process times. 9 | func GetUsage() (Usage, error) { 10 | return Usage{}, errors.New("not supported on GOOS=js") 11 | } 12 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/usage_posix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !windows,!js 5 | 6 | package sysinfo 7 | 8 | import ( 9 | "syscall" 10 | "time" 11 | ) 12 | 13 | func timevalToDuration(tv syscall.Timeval) time.Duration { 14 | return time.Duration(tv.Nano()) * time.Nanosecond 15 | } 16 | 17 | // GetUsage gathers process times. 18 | func GetUsage() (Usage, error) { 19 | ru := syscall.Rusage{} 20 | err := syscall.Getrusage(syscall.RUSAGE_SELF, &ru) 21 | if err != nil { 22 | return Usage{}, err 23 | } 24 | 25 | return Usage{ 26 | System: timevalToDuration(ru.Stime), 27 | User: timevalToDuration(ru.Utime), 28 | }, nil 29 | } 30 | -------------------------------------------------------------------------------- /v3/internal/sysinfo/usage_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package sysinfo 5 | 6 | import ( 7 | "syscall" 8 | "time" 9 | ) 10 | 11 | func filetimeToDuration(ft *syscall.Filetime) time.Duration { 12 | ns := ft.Nanoseconds() 13 | return time.Duration(ns) 14 | } 15 | 16 | // GetUsage gathers process times. 17 | func GetUsage() (Usage, error) { 18 | var creationTime syscall.Filetime 19 | var exitTime syscall.Filetime 20 | var kernelTime syscall.Filetime 21 | var userTime syscall.Filetime 22 | 23 | handle, err := syscall.GetCurrentProcess() 24 | if err != nil { 25 | return Usage{}, err 26 | } 27 | 28 | err = syscall.GetProcessTimes(handle, &creationTime, &exitTime, &kernelTime, &userTime) 29 | if err != nil { 30 | return Usage{}, err 31 | } 32 | 33 | return Usage{ 34 | System: filetimeToDuration(&kernelTime), 35 | User: filetimeToDuration(&userTime), 36 | }, nil 37 | } 38 | -------------------------------------------------------------------------------- /v3/internal/tools/interface-wrapping/driver_conn.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "used in wrapping driver.Conn", 3 | "variable_name": "conn", 4 | "test_variable_name": "conn.original", 5 | "required_interfaces": [ 6 | "driver.Conn" 7 | ], 8 | "optional_interfaces": [ 9 | "driver.ConnBeginTx", 10 | "driver.ConnPrepareContext", 11 | "driver.Execer", 12 | "driver.ExecerContext", 13 | "driver.NamedValueChecker", 14 | "driver.Pinger", 15 | "driver.Queryer", 16 | "driver.QueryerContext", 17 | "driver.SessionResetter" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /v3/internal/tools/interface-wrapping/driver_driver.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "used in wrapping driver.Driver", 3 | "variable_name": "dv", 4 | "test_variable_name": "dv.original", 5 | "required_interfaces": [ 6 | "driver.Driver" 7 | ], 8 | "optional_interfaces": [ 9 | "driver.DriverContext" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /v3/internal/tools/interface-wrapping/driver_stmt.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "used in wrapping driver.Stmt", 3 | "variable_name": "stmt", 4 | "test_variable_name": "stmt.original", 5 | "required_interfaces": [ 6 | "driver.Stmt" 7 | ], 8 | "optional_interfaces": [ 9 | "driver.ColumnConverter", 10 | "driver.NamedValueChecker", 11 | "driver.StmtExecContext", 12 | "driver.StmtQueryContext" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /v3/internal/tools/interface-wrapping/response_writer.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "used in internal_response_writer.go", 3 | "variable_name": "rw", 4 | "test_variable_name": "rw.original", 5 | "required_interfaces": [ 6 | "http.ResponseWriter" 7 | ], 8 | "optional_interfaces": [ 9 | "http.CloseNotifier", 10 | "http.Flusher", 11 | "http.Hijacker", 12 | "io.ReaderFrom" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /v3/internal/tools/rules/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "encoding/json" 8 | "fmt" 9 | "io/ioutil" 10 | "os" 11 | 12 | "github.com/newrelic/go-agent/v3/internal" 13 | ) 14 | 15 | func fail(reason string) { 16 | fmt.Println(reason) 17 | os.Exit(1) 18 | } 19 | 20 | func main() { 21 | if len(os.Args) < 3 { 22 | fail("improper usage: ./rules path/to/reply_file input") 23 | } 24 | 25 | connectReplyFile := os.Args[1] 26 | name := os.Args[2] 27 | 28 | data, err := ioutil.ReadFile(connectReplyFile) 29 | if nil != err { 30 | fail(fmt.Sprintf("unable to open '%s': %s", connectReplyFile, err)) 31 | } 32 | 33 | var reply internal.ConnectReply 34 | err = json.Unmarshal(data, &reply) 35 | if nil != err { 36 | fail(fmt.Sprintf("unable unmarshal reply: %s", err)) 37 | } 38 | 39 | // Metric Rules 40 | out := reply.MetricRules.Apply(name) 41 | fmt.Println("metric rules applied:", out) 42 | 43 | // Url Rules + Txn Name Rules + Segment Term Rules 44 | 45 | out = internal.CreateFullTxnName(name, &reply, true) 46 | fmt.Println("treated as web txn name:", out) 47 | 48 | out = internal.CreateFullTxnName(name, &reply, false) 49 | fmt.Println("treated as backround txn name:", out) 50 | } 51 | -------------------------------------------------------------------------------- /v3/internal/trace_id_generator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | import "testing" 7 | 8 | func TestTraceIDGenerator(t *testing.T) { 9 | tg := NewTraceIDGenerator(12345) 10 | traceID := tg.GenerateTraceID() 11 | if traceID != "1ae969564b34a33ecd1af05fe6923d6d" { 12 | t.Error(traceID) 13 | } 14 | spanID := tg.GenerateSpanID() 15 | if spanID != "e71870997d38ef60" { 16 | t.Error(spanID) 17 | } 18 | if p := tg.Float32(); p != 0.05700199 { 19 | t.Error(p) 20 | } 21 | } 22 | 23 | func BenchmarkTraceIDGenerator(b *testing.B) { 24 | tg := NewTraceIDGenerator(12345) 25 | 26 | b.ResetTimer() 27 | b.ReportAllocs() 28 | 29 | for i := 0; i < b.N; i++ { 30 | if id := tg.GenerateSpanID(); id == "" { 31 | b.Fatal(id) 32 | } 33 | } 34 | } 35 | 36 | func BenchmarkTraceIDGeneratorParallel(b *testing.B) { 37 | tg := NewTraceIDGenerator(12345) 38 | 39 | b.ResetTimer() 40 | b.ReportAllocs() 41 | 42 | b.RunParallel(func(p *testing.PB) { 43 | for p.Next() { 44 | if id := tg.GenerateSpanID(); id == "" { 45 | b.Fatal(id) 46 | } 47 | } 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /v3/internal/usage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | import ( 7 | "strings" 8 | "sync" 9 | ) 10 | 11 | var ( 12 | trackMutex sync.Mutex 13 | trackMetrics []string 14 | ) 15 | 16 | // TrackUsage helps track which integration packages are used. 17 | func TrackUsage(s ...string) { 18 | trackMutex.Lock() 19 | defer trackMutex.Unlock() 20 | 21 | m := "Supportability/" + strings.Join(s, "/") 22 | trackMetrics = append(trackMetrics, m) 23 | } 24 | 25 | // GetUsageSupportabilityMetrics returns supportability metric names. 26 | func GetUsageSupportabilityMetrics() []string { 27 | trackMutex.Lock() 28 | defer trackMutex.Unlock() 29 | 30 | names := make([]string, 0, len(trackMetrics)) 31 | for _, s := range trackMetrics { 32 | names = append(names, s) 33 | } 34 | return names 35 | } 36 | -------------------------------------------------------------------------------- /v3/internal/utilities.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | import ( 7 | "bytes" 8 | "encoding/json" 9 | "fmt" 10 | "reflect" 11 | "runtime" 12 | "time" 13 | ) 14 | 15 | // FloatSecondsToDuration turns a float64 in seconds into a time.Duration. 16 | func FloatSecondsToDuration(seconds float64) time.Duration { 17 | nanos := seconds * 1000 * 1000 * 1000 18 | return time.Duration(nanos) * time.Nanosecond 19 | } 20 | 21 | // CompactJSONString removes the whitespace from a JSON string. This function 22 | // will panic if the string provided is not valid JSON. Thus is must only be 23 | // used in testing code! 24 | func CompactJSONString(js string) string { 25 | buf := new(bytes.Buffer) 26 | if err := json.Compact(buf, []byte(js)); err != nil { 27 | panic(fmt.Errorf("unable to compact JSON: %v", err)) 28 | } 29 | return buf.String() 30 | } 31 | 32 | // HandlerName return name of a function. 33 | func HandlerName(h interface{}) string { 34 | if h == nil { 35 | return "" 36 | } 37 | t := reflect.ValueOf(h).Type() 38 | if t.Kind() == reflect.Func { 39 | if pointer := runtime.FuncForPC(reflect.ValueOf(h).Pointer()); pointer != nil { 40 | return pointer.Name() 41 | } 42 | } 43 | return "" 44 | } 45 | -------------------------------------------------------------------------------- /v3/internal/utilities_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package internal 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestFloatSecondsToDuration(t *testing.T) { 12 | if d := FloatSecondsToDuration(0.123); d != 123*time.Millisecond { 13 | t.Error(d) 14 | } 15 | if d := FloatSecondsToDuration(456.0); d != 456*time.Second { 16 | t.Error(d) 17 | } 18 | } 19 | 20 | func TestCompactJSON(t *testing.T) { 21 | in := ` 22 | { "zip": 1}` 23 | out := CompactJSONString(in) 24 | if out != `{"zip":1}` { 25 | t.Fatal(in, out) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /v3/internal/utilization/fqdn.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build go1.8 5 | 6 | package utilization 7 | 8 | import ( 9 | "context" 10 | "net" 11 | "strings" 12 | ) 13 | 14 | func lookupAddr(addr string) ([]string, error) { 15 | ctx, cancel := context.WithTimeout(context.Background(), lookupAddrTimeout) 16 | defer cancel() 17 | 18 | r := &net.Resolver{} 19 | 20 | return r.LookupAddr(ctx, addr) 21 | } 22 | 23 | func getFQDN(candidateIPs []string) string { 24 | for _, ip := range candidateIPs { 25 | names, _ := lookupAddr(ip) 26 | if len(names) > 0 { 27 | return strings.TrimSuffix(names[0], ".") 28 | } 29 | } 30 | return "" 31 | } 32 | -------------------------------------------------------------------------------- /v3/internal/utilization/fqdn_pre18.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !go1.8 5 | 6 | package utilization 7 | 8 | // net.Resolver.LookupAddr was added in Go 1.8, and net.LookupAddr does not have 9 | // a controllable timeout, so we skip the optional full_hostname on pre 1.8 10 | // versions. 11 | 12 | func getFQDN(candidateIPs []string) string { 13 | return "" 14 | } 15 | -------------------------------------------------------------------------------- /v3/newrelic/apdex.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import "time" 7 | 8 | // apdexZone is a transaction classification. 9 | type apdexZone int 10 | 11 | // https://en.wikipedia.org/wiki/Apdex 12 | const ( 13 | apdexNone apdexZone = iota 14 | apdexSatisfying 15 | apdexTolerating 16 | apdexFailing 17 | ) 18 | 19 | // apdexFailingThreshold calculates the threshold at which the transaction is 20 | // considered a failure. 21 | func apdexFailingThreshold(threshold time.Duration) time.Duration { 22 | return 4 * threshold 23 | } 24 | 25 | // calculateApdexZone calculates the apdex based on the transaction duration and 26 | // threshold. 27 | // 28 | // Note that this does not take into account whether or not the transaction 29 | // had an error. That is expected to be done by the caller. 30 | func calculateApdexZone(threshold, duration time.Duration) apdexZone { 31 | if duration <= threshold { 32 | return apdexSatisfying 33 | } 34 | if duration <= apdexFailingThreshold(threshold) { 35 | return apdexTolerating 36 | } 37 | return apdexFailing 38 | } 39 | 40 | func (zone apdexZone) label() string { 41 | switch zone { 42 | case apdexSatisfying: 43 | return "S" 44 | case apdexTolerating: 45 | return "T" 46 | case apdexFailing: 47 | return "F" 48 | default: 49 | return "" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /v3/newrelic/apdex_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func dur(d int) time.Duration { 12 | return time.Duration(d) 13 | } 14 | 15 | func TestCalculateApdexZone(t *testing.T) { 16 | if z := calculateApdexZone(dur(10), dur(1)); z != apdexSatisfying { 17 | t.Fatal(z) 18 | } 19 | if z := calculateApdexZone(dur(10), dur(10)); z != apdexSatisfying { 20 | t.Fatal(z) 21 | } 22 | if z := calculateApdexZone(dur(10), dur(11)); z != apdexTolerating { 23 | t.Fatal(z) 24 | } 25 | if z := calculateApdexZone(dur(10), dur(40)); z != apdexTolerating { 26 | t.Fatal(z) 27 | } 28 | if z := calculateApdexZone(dur(10), dur(41)); z != apdexFailing { 29 | t.Fatal(z) 30 | } 31 | if z := calculateApdexZone(dur(10), dur(100)); z != apdexFailing { 32 | t.Fatal(z) 33 | } 34 | } 35 | 36 | func TestApdexLabel(t *testing.T) { 37 | if out := apdexSatisfying.label(); "S" != out { 38 | t.Fatal(out) 39 | } 40 | if out := apdexTolerating.label(); "T" != out { 41 | t.Fatal(out) 42 | } 43 | if out := apdexFailing.label(); "F" != out { 44 | t.Fatal(out) 45 | } 46 | if out := apdexNone.label(); "" != out { 47 | t.Fatal(out) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /v3/newrelic/custom_events.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import "time" 7 | 8 | type customEvents struct { 9 | *analyticsEvents 10 | } 11 | 12 | func newCustomEvents(max int) *customEvents { 13 | return &customEvents{ 14 | analyticsEvents: newAnalyticsEvents(max), 15 | } 16 | } 17 | 18 | func (cs *customEvents) Add(e *customEvent) { 19 | // For the Go Agent, customEvents are added to the application, not the transaction. 20 | // As a result, customEvents do not inherit their priority from the transaction, though 21 | // they are still sampled according to priority sampling. 22 | priority := newPriority() 23 | cs.addEvent(analyticsEvent{priority, e}) 24 | } 25 | 26 | func (cs *customEvents) MergeIntoHarvest(h *harvest) { 27 | h.CustomEvents.mergeFailed(cs.analyticsEvents) 28 | } 29 | 30 | func (cs *customEvents) Data(agentRunID string, harvestStart time.Time) ([]byte, error) { 31 | return cs.CollectorJSON(agentRunID) 32 | } 33 | 34 | func (cs *customEvents) EndpointMethod() string { 35 | return cmdCustomEvents 36 | } 37 | -------------------------------------------------------------------------------- /v3/newrelic/custom_metric.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | // customMetric is a custom metric. 7 | type customMetric struct { 8 | RawInputName string 9 | Value float64 10 | } 11 | 12 | // MergeIntoHarvest implements Harvestable. 13 | func (m customMetric) MergeIntoHarvest(h *harvest) { 14 | h.Metrics.addValue(customMetricName(m.RawInputName), "", m.Value, unforced) 15 | } 16 | -------------------------------------------------------------------------------- /v3/newrelic/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // Package newrelic provides instrumentation for Go applications. 5 | // 6 | // Additional documention available here: 7 | // 8 | // https://github.com/newrelic/go-agent/blob/master/GETTING_STARTED.md 9 | // 10 | // https://github.com/newrelic/go-agent/blob/master/GUIDE.md 11 | // 12 | package newrelic 13 | -------------------------------------------------------------------------------- /v3/newrelic/json_object_writer_test.go: -------------------------------------------------------------------------------- 1 | package newrelic 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | func BenchmarkStringFieldShort(b *testing.B) { 9 | writer := jsonFieldsWriter{ 10 | buf: bytes.NewBuffer(make([]byte, 300)), 11 | } 12 | 13 | for i := 0; i < b.N; i++ { 14 | writer.stringField("testkey", "this is a short string") 15 | } 16 | } 17 | 18 | func BenchmarkStringFieldLong(b *testing.B) { 19 | writer := jsonFieldsWriter{ 20 | buf: bytes.NewBuffer(make([]byte, 300)), 21 | } 22 | 23 | for i := 0; i < b.N; i++ { 24 | writer.stringField("testkey", "this is a long string that will capture the runtime performance impact that writing more bytes has on this function") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v3/newrelic/obfuscate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import ( 7 | "encoding/base64" 8 | "errors" 9 | ) 10 | 11 | // deobfuscate deobfuscates a byte array. 12 | func deobfuscate(in string, key []byte) ([]byte, error) { 13 | if len(key) == 0 { 14 | return nil, errors.New("key cannot be zero length") 15 | } 16 | 17 | decoded, err := base64.StdEncoding.DecodeString(in) 18 | if err != nil { 19 | return nil, err 20 | } 21 | 22 | out := make([]byte, len(decoded)) 23 | for i, c := range decoded { 24 | out[i] = c ^ key[i%len(key)] 25 | } 26 | 27 | return out, nil 28 | } 29 | 30 | // obfuscate obfuscates a byte array for transmission in CAT and RUM. 31 | func obfuscate(in, key []byte) (string, error) { 32 | if len(key) == 0 { 33 | return "", errors.New("key cannot be zero length") 34 | } 35 | 36 | out := make([]byte, len(in)) 37 | for i, c := range in { 38 | out[i] = c ^ key[i%len(key)] 39 | } 40 | 41 | return base64.StdEncoding.EncodeToString(out), nil 42 | } 43 | -------------------------------------------------------------------------------- /v3/newrelic/priority_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import ( 7 | "testing" 8 | ) 9 | 10 | func TestIsLowerPriority(t *testing.T) { 11 | low := priority(0.0) 12 | middle := priority(0.1) 13 | high := priority(0.999999) 14 | 15 | if !low.isLowerPriority(middle) { 16 | t.Error(low, middle) 17 | } 18 | 19 | if high.isLowerPriority(middle) { 20 | t.Error(high, middle) 21 | } 22 | 23 | if high.isLowerPriority(high) { 24 | t.Error(high, high) 25 | } 26 | } 27 | 28 | func TestTraceStateFormat(t *testing.T) { 29 | testcases := []struct { 30 | input float64 31 | expected string 32 | }{ 33 | {input: 0, expected: "0"}, 34 | {input: 0.1, expected: "0.1"}, 35 | {input: 0.7654321, expected: "0.765432"}, 36 | {input: 10.7654321, expected: "10.765432"}, 37 | {input: 0.99999999999, expected: "1"}, 38 | } 39 | 40 | for _, tc := range testcases { 41 | p := priority(tc.input) 42 | if out := p.traceStateFormat(); out != tc.expected { 43 | t.Errorf("wrong priority format for %f: expected=%s actual=%s", tc.input, tc.expected, out) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /v3/newrelic/rules_cache.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import "sync" 7 | 8 | // rulesCache is designed to avoid applying url-rules, txn-name-rules, and 9 | // segment-rules since regexes are expensive! 10 | type rulesCache struct { 11 | sync.RWMutex 12 | cache map[rulesCacheKey]string 13 | maxCacheSize int 14 | } 15 | 16 | type rulesCacheKey struct { 17 | isWeb bool 18 | inputName string 19 | } 20 | 21 | func newRulesCache(maxCacheSize int) *rulesCache { 22 | return &rulesCache{ 23 | cache: make(map[rulesCacheKey]string, maxCacheSize), 24 | maxCacheSize: maxCacheSize, 25 | } 26 | } 27 | 28 | func (cache *rulesCache) find(inputName string, isWeb bool) string { 29 | if nil == cache { 30 | return "" 31 | } 32 | cache.RLock() 33 | defer cache.RUnlock() 34 | 35 | return cache.cache[rulesCacheKey{ 36 | inputName: inputName, 37 | isWeb: isWeb, 38 | }] 39 | } 40 | 41 | func (cache *rulesCache) set(inputName string, isWeb bool, finalName string) { 42 | if nil == cache { 43 | return 44 | } 45 | cache.Lock() 46 | defer cache.Unlock() 47 | 48 | if len(cache.cache) >= cache.maxCacheSize { 49 | return 50 | } 51 | cache.cache[rulesCacheKey{ 52 | inputName: inputName, 53 | isWeb: isWeb, 54 | }] = finalName 55 | } 56 | -------------------------------------------------------------------------------- /v3/newrelic/trace_observer_1_8.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !go1.9 5 | 6 | package newrelic 7 | 8 | import ( 9 | "github.com/newrelic/go-agent/v3/internal" 10 | ) 11 | 12 | func newTraceObserver(runID internal.AgentRunID, requestHeadersMap map[string]string, cfg observerConfig) (traceObserver, error) { 13 | return nil, errUnsupportedVersion 14 | } 15 | 16 | const ( 17 | // versionSupports8T records whether we are using a supported version of Go for 18 | // Infinite Tracing 19 | versionSupports8T = false 20 | grpcVersion = "not-installed" 21 | ) 22 | 23 | func expectObserverEvents(v internal.Validator, events *analyticsEvents, expect []internal.WantEvent, extraAttributes map[string]interface{}) { 24 | } 25 | -------------------------------------------------------------------------------- /v3/newrelic/trace_observer_1_8_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !go1.9 5 | // This build tag is necessary because Infinite Tracing is only supported for Go version 1.9 and up 6 | 7 | package newrelic 8 | 9 | import "testing" 10 | 11 | func TestSupported8TVersion(t *testing.T) { 12 | _, err := NewApplication( 13 | ConfigLicense("1234567890123456789012345678901234567890"), 14 | ConfigAppName("name"), 15 | func(c *Config) { 16 | c.InfiniteTracing.TraceObserver.Host = "localhost" 17 | }, 18 | ) 19 | if nil == err { 20 | t.Error("expected unsupported version error for 8T but got none") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /v3/newrelic/transport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build go1.13 5 | 6 | package newrelic 7 | 8 | import ( 9 | "net" 10 | "net/http" 11 | "time" 12 | ) 13 | 14 | var ( 15 | // collectorDefaultTransport is the http.Transport to be used with 16 | // communication to the collector backend if a Transport is not set on the 17 | // Config. 18 | collectorDefaultTransport = &http.Transport{ 19 | Proxy: http.ProxyFromEnvironment, 20 | DialContext: (&net.Dialer{ 21 | Timeout: 30 * time.Second, 22 | KeepAlive: 30 * time.Second, 23 | DualStack: true, 24 | }).DialContext, 25 | ForceAttemptHTTP2: true, // added in go 1.13 26 | MaxIdleConns: 100, 27 | MaxIdleConnsPerHost: 100, // note: different from default global transport 28 | IdleConnTimeout: 90 * time.Second, 29 | TLSHandshakeTimeout: 10 * time.Second, 30 | ExpectContinueTimeout: 1 * time.Second, 31 | } 32 | ) 33 | -------------------------------------------------------------------------------- /v3/newrelic/transport_1_12.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | // +build !go1.13 5 | 6 | package newrelic 7 | 8 | import ( 9 | "net" 10 | "net/http" 11 | "time" 12 | ) 13 | 14 | var ( 15 | // collectorDefaultTransport is the http.Transport to be used with 16 | // communication to the collector backend if a Transport is not set on the 17 | // Config. 18 | collectorDefaultTransport = &http.Transport{ 19 | Proxy: http.ProxyFromEnvironment, 20 | DialContext: (&net.Dialer{ 21 | Timeout: 30 * time.Second, 22 | KeepAlive: 30 * time.Second, 23 | DualStack: true, 24 | }).DialContext, 25 | MaxIdleConns: 100, 26 | MaxIdleConnsPerHost: 100, // note: different from default global transport 27 | IdleConnTimeout: 90 * time.Second, 28 | TLSHandshakeTimeout: 10 * time.Second, 29 | ExpectContinueTimeout: 1 * time.Second, 30 | } 31 | ) 32 | -------------------------------------------------------------------------------- /v3/newrelic/url.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import "net/url" 7 | 8 | // safeURL removes sensitive information from a URL. 9 | func safeURL(u *url.URL) string { 10 | if nil == u { 11 | return "" 12 | } 13 | if "" != u.Opaque { 14 | // If the URL is opaque, we cannot be sure if it contains 15 | // sensitive information. 16 | return "" 17 | } 18 | 19 | // Omit user, query, and fragment information for security. 20 | ur := url.URL{ 21 | Scheme: u.Scheme, 22 | Host: u.Host, 23 | Path: u.Path, 24 | } 25 | return ur.String() 26 | } 27 | 28 | // safeURLFromString removes sensitive information from a URL. 29 | func safeURLFromString(rawurl string) string { 30 | u, err := url.Parse(rawurl) 31 | if nil != err { 32 | return "" 33 | } 34 | return safeURL(u) 35 | } 36 | 37 | // hostFromURL returns the URL's host. 38 | func hostFromURL(u *url.URL) string { 39 | if nil == u { 40 | return "" 41 | } 42 | if "" != u.Opaque { 43 | return "opaque" 44 | } 45 | return u.Host 46 | } 47 | -------------------------------------------------------------------------------- /v3/newrelic/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 New Relic Corporation. All rights reserved. 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | package newrelic 5 | 6 | import ( 7 | "runtime" 8 | 9 | "github.com/newrelic/go-agent/v3/internal" 10 | ) 11 | 12 | const ( 13 | // Version is the full string version of this Go Agent. 14 | Version = "3.39.0" 15 | ) 16 | 17 | var ( 18 | goVersionSimple = minorVersion(runtime.Version()) 19 | ) 20 | 21 | func init() { 22 | internal.TrackUsage("Go", "Version", Version) 23 | internal.TrackUsage("Go", "Runtime", "Version", goVersionSimple) 24 | internal.TrackUsage("Go", "gRPC", "Version", grpcVersion) 25 | } 26 | --------------------------------------------------------------------------------