-
Notifications
You must be signed in to change notification settings - Fork 173
feat(go/adbc): prototype OpenTelemetry trace file exporter in go driver #2729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(go/adbc): prototype OpenTelemetry trace file exporter in go driver #2729
Conversation
|
@davidhcoe / @CurtHagenlocher |
zeroshade
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, but there's lots of areas that can be simplified or otherwise more concise. Plus a few spots where you lose the span context
zeroshade
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few more comments, but this is looking good to me!
@lidavidm any comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing docstrings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is ADBC handling this? If it's for testing, isn't the standard to dump to OTLP and let the OTLP collector dump to stdout/file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This handles the scenario
- when the end-user is not authorized or doesn't want to install/deploy/configure an OTLP Collector
- the caller cannot directly capture
stdout- for example when a background process is started
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lidavidm - Think about the scenario like what exists for ODBC drivers. If a user has an issue with a product that consumes the driver, they will need to capture logs to send to the support team of said product. The file writer enables the capturing of the text-based files so the user can send those logs, in addition to whatever product logs may exist.
If we call this through the C# interop layer (like we do with Snowflake and Flight SQL today), then the only way to get the captured output is via the log files because there is no stdout capability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't integrate with the existing logging mechanism, though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, I'd ask
(1) let's not dump stuff directly into $HOME; can we use something more proper/follow desktop standards?
(2) adbcfile is a bit of an odd name to me, but I guess we're stuck trying not to accidentally alias some (future) standard OTel sink somehow
(3) Ideally we could use the existing log config as the sink? Or unify them? We currently have an API to set an slog sink; it would be best if there was at least some plan to migrate/settle on a single log provider, since OTel has its own logging API. (Thankfully, the current logging API is also in ext.go so I'm more comfortable updating it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is there any upstream/community decision or discussion on file exporters? It seems odd to me that this isn't provided at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't integrate with the existing logging mechanism, though...
Previously, I was not able to successfully get log outputs when I call through the C# interop layer. I only tried with Snowflake. I set the ADBC_DRIVER_SNOWFLAKE_LOG_LEVEL environment variable but couldn't find if/where the log output was written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Migration from SLOG
- Logging levels don't really apply to traces. Traces have attributes, statuses or other properties which could be filtered before export. But that would be complicated to configure. That is a good candidate for using OTel Collector.
- Currently, the
slogoutput (ingo) is set to output tostderr. Which, as @davidhcoe notes, is difficult to redirect to a file in his scenario where new processes are being spawned in the background. - Maybe we could transition such that if ADBC_DRIVER_{driver-name}_LOG_LEVEL is set to one of [
debug,info,warn,warning,error], that would enable OTel traces to be exported tostdout(orstderr). That is, be the equivalent ofOTEL_TRACES_EXPORTER=console
2. Location of trace files in file system
- I would just suggest that the location be portably available to the executing user.
- It ensures the user has the permission to write the files.
- It reduces a possible need for configuration option if the default is reasonable.
- It is more likely that it doesn't inadvertently expose the files to other users in the system.
- Your suggestion of
os.UserConfigDir()is a good choice.
3. Choice of adbcfile for OTEL_TRACES_EXPORTER
- This seems to be the the most obvious choice given the existing values for this configuration. It avoids the possible name clash.
- From my exposure to the OTel SDK
consoleexporters in different languages (goandC#) - they have different schema format. That is the main dilemma of why an existingfileexporter has not be defined and published, yet. From my opinion, I don't think the schema matters for this use case - debug. If it was going to be consumed by some automation (i.e., OTel Collector), then schema would be important. - They (OTel) seem to be stuck on the schema format. But I think also they have the requirement that the contents could be used for an automated pipeline. So schema is important in this scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OTel conceives of logs and traces as part of the same thing, which is why I ask (and OTel has its own logging standard) - so ideally we would have some plan to unify logging, if not right now
|
|
||
| defer func() { | ||
| if !st.SetErrorOnSpan(span, err) { | ||
| span.SetAttributes(attribute.Int64("db.response.returned_rows", numRows)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is -1 ending up here potentially problematic for downstream consumers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear: does OTel accept -1 for this attribute? Since ADBC specifies -1 as the return value for when the number of rows is unknown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also do we need a utility for this given this pattern seems to recur?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Negative numbers are not a problem.
|
|
||
| defer func() { | ||
| if !st.SetErrorOnSpan(span, err) { | ||
| span.SetAttributes(attribute.Int64("db.response.returned_rows", numRows)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear: does OTel accept -1 for this attribute? Since ADBC specifies -1 as the return value for when the number of rows is unknown.
|
|
||
| defer func() { | ||
| if !st.SetErrorOnSpan(span, err) { | ||
| span.SetAttributes(attribute.Int64("db.response.returned_rows", numRows)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also do we need a utility for this given this pattern seems to recur?
Yes. I agree. In general, I'd say that I'm not really satisfied with the transparency of this instrumentation example. I was going to look at some other possible solutions like evaluating the original source as a lambda expressions. This was only intended to give an example of instrumentation. We're going to need to provide a more complete instrumentation for each of the drivers. I'd suggest we look at improving the ease and reusability when we tackle instrumentation. |
|
@zeroshade any more comments? I still think we need to unify log/trace config at some point, but we don't have to do that here |
zeroshade
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now. I agree that we can address unifying logs and otel as a follow up
lidavidm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Initial implementation of integrating OpenTelemetry tracing into the go drivers.
Instantiates an OTel exporter in the driverbase.database based on the value of the environment variable
OTEL_TRACES_EXPORTER. Supports the valuesnone,otlp,consoleandadbcfilenone(default) indicates no tracing should be exported.otlpindicates tracing should be exported to an OTLP receiver. By default, the endpoint is http://localhost:4318 using HTTP/protobufs protocol. The OTLP exporter can be configured using the environment variables described here.consoleindicates tracing should be exported tostdout.adbcfileindicates tracing should be exported to a tracing file folder using a rotating file mechanism. The default folder is~/.adbc/traces/and the files are named according the driver used and the (UTC) time they were first created. Files are generated such that no file is greater than ~ 1 MB and there are never more than 100 archived trace files.If the OTLP exporter option is chosen, a OTLP receiver is required. One option is the OpenTelemetry Collector.
This PR includes some instrumentation in the Snowflake driver to indicate how to add trace information.
Resolves: #2210