dylibso / observe-sdk

Continuous runtime observablity SDKs to monitor WebAssembly code.
https://dev.dylibso.com/docs/observe/overview
Apache License 2.0
157 stars 7 forks source link

feat: add go http/grpc otel adapter #125

Closed nilslice closed 1 year ago

nilslice commented 1 year ago

Moving this to ready for review, assuming there's just some odd inconsistency with the Jaeger all-in-one server used to test.

According to practically everywhere Jaeger & OpenTelemetry cross paths in docs and READMEs, Jaeger supports OTLP and has deprecated the exporters which used to provide translation to compatible traces.

As mentioned in the comment below, Honeycomb's OTLP support works perfectly with the traces this Adapter is sending, so I think we're OK.

Update:

This should now be in working condition for testing on Jaeger. Using the same commands in the comment below, this adapter will emit to Jaeger running in the example container.

nilslice commented 1 year ago

Update: Resolved


Currently seeing an issue with traceId and spanId lengths, causing the server to reject requests. However, it seems to me that these IDs are the correct sizes:

Example from below: TraceId: 4d257aaaae76822d0b17fa407547bfb4 SpanId: 12f9f92e17d58634

Maybe @bhelx could confirm, but based on what I've seen in OpenTelemetry docs, these IDs should work fine. Also, these are the same format IDs generated and used successfully in other Adapters that use OTEL format.

I'm testing this against the Jaeger Docker image as such:

docker run --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  jaegertracing/all-in-one:1.35

(port 4318 is for HTTP, 4317 for gRPC)

Then running the go bin example for this otel adapter:

cd go
echo "this is a test" | go run bin/opentelemetry/main.go test/count_vowels.instr.wasm

For HTTP connections, the output is:

4
2023/09/21 22:08:42 failed to upload wasm traces to otel endpoint failed to send to http://localhost:4318/v1/traces: 400 Bad Request

For gRPC connections, the output is:

4
2023/09/21 22:11:15 failed to upload wasm traces to otel endpoint rpc error: code = Internal desc = grpc: error unmarshalling request: invalid length for TraceID
Full resource spans sent as per the `UploadTraces` function signature: [resource: { attributes: { key: "service.name" value: { string_value: "golang" } } } scope_spans: { spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "070b846016f0e240" name: "_start" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832065398 end_time_unix_nano: 1695354524832307736 attributes: { key: "function-name" value: { string_value: "function-call-_start" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "12f9f92e17d58634" parent_span_id: "070b846016f0e240" name: "__main_void" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832074431 end_time_unix_nano: 1695354524832300803 attributes: { key: "function-name" value: { string_value: "function-call-__main_void" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "4a4f8f1dbe26378e" parent_span_id: "12f9f92e17d58634" name: "std::rt::lang_start_internal" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832075767 end_time_unix_nano: 1695354524832299955 attributes: { key: "function-name" value: { string_value: "function-call-std::rt::lang_start_internal" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "17c8ffd4fda4f2e0" parent_span_id: "4a4f8f1dbe26378e" name: "std::sys_common::backtrace::_rust_begin_short_backtrace" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832110638 end_time_unix_nano: 1695354524832282492 attributes: { key: "function-name" value: { string_value: "function-call-std::sys_common::backtrace::_rust_begin_short_backtrace" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "5f543a5b280d054f" parent_span_id: "17c8ffd4fda4f2e0" name: "std::io::stdio::Stdin::read_line" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832127694 end_time_unix_nano: 1695354524832172707 attributes: { key: "function-name" value: { string_value: "function-call-std::io::stdio::Stdin::read_line" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "30607cd4122fbafb" parent_span_id: "5f543a5b280d054f" name: "std::io::read_until" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832129063 end_time_unix_nano: 1695354524832169632 attributes: { key: "function-name" value: { string_value: "function-call-std::io::read_until" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "009ddea3d56baf73" parent_span_id: "17c8ffd4fda4f2e0" name: "std::io::stdio::print" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832174408 end_time_unix_nano: 1695354524832268988 attributes: { key: "function-name" value: { string_value: "function-call-std::io::stdio::print" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "0d4969e9995b3271" parent_span_id: "009ddea3d56baf73" name: "<&std::io::stdio::Stdout as std::io::Write>::write_fmt" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832189876 end_time_unix_nano: 1695354524832267689 attributes: { key: "function-name" value: { string_value: "function-call-<&std::io::stdio::Stdout as std::io::Write>::write_fmt" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "38b3b1dfe6123852" parent_span_id: "0d4969e9995b3271" name: "core::fmt::write" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832191177 end_time_unix_nano: 1695354524832239799 attributes: { key: "function-name" value: { string_value: "function-call-core::fmt::write" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } } spans: { trace_id: "4d257aaaae76822d0b17fa407547bfb4" span_id: "3c0f499b21d29c44" parent_span_id: "38b3b1dfe6123852" name: "::write_all" kind: SPAN_KIND_INTERNAL start_time_unix_nano: 1695354524832209809 end_time_unix_nano: 1695354524832238461 attributes: { key: "function-name" value: { string_value: "function-call-::write_all" } } attributes: { key: "http.url" value: { string_value: "https://example.com/my-endpoint" } } attributes: { key: "http.status_code" value: { string_value: "200" } } attributes: { key: "http.client_ip" value: { string_value: "66.210.227.34" } } } } ]

To prove the trace and span ID generator is working, I swapped out the HTTP endpoint for Honeycomb's and added our team API key to the header. Sending traces from the same program execution result in a successful upload:

image