-
Notifications
You must be signed in to change notification settings - Fork 853
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!: use semver to determine API compatibility #1772
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1772 +/- ##
==========================================
- Coverage 92.18% 92.05% -0.14%
==========================================
Files 167 164 -3
Lines 5845 5560 -285
Branches 1256 1208 -48
==========================================
- Hits 5388 5118 -270
+ Misses 457 442 -15
|
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.
generally looks fine, I have just concerns with regards the error handling which should be imho changed, so we don't break / stop the end user functionality
const api = _global[GLOBAL_OPENTELEMETRY_API_KEY]!; | ||
if (api[type]) { | ||
// already registered an API of this type | ||
throw new Error( |
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.
shouldn't we warn here only instead of throwing an error ?
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.
Yeah does the spec require us to never throw on the API ?
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.
The spec strongly discourages throwing. I can change it, but the behavior of doing nothing is potentially confusing. This should only be called during trace setup and never again so it seems unlikely to throw. I thought it would be fine in this case. I can change it to warn though if that's better.
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.
I would prefer a warn since users generally think there are errors anyway (since the console logger doesn't log the level by default)
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.
there is no logger here because we're in the API. It has to be console.warn
. Is that OK?
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.
any CLI tool written in nodejs could potentially have an expected output to be parsed by other tools. If we log unexpectedly we change that output.
Simple example, a cli that scrapes the github API and outputs the open issues on a project as JSON to be consumed by jq
and other tools.
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.
Exactly. It's not nodejs which runs into issues it's the specific user application.
I remember at least one case where I broke an application by logging to stderr because this was seen as error by the caller.
And logging to sdtout tends to break everything where a caller reads result from stdout.
If documentation clearly states that an API may throw it's up to the user (and all our samples) to add a try/catch and log/exit/...
A log to console can't be catched by user (except by monkey patching console but I don't think we want users to do this).
We could change the API to return a boolean instead of throwing. But this results in loosing the reason why it failed. We could return an error string or similar but I don't think these are nice APIs.
This is an API only used once during startup. Throwing there doesn't force users to clutter their whole codebase with try/catches. Therefore I think it's ok to throw here.
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.
If documentation clearly states that an API may throw it's up to the user (and all our samples) to add a try/catch and log/exit/...
I don't think expecting users to try/catch when trying to setup the sdk or a instrumentation would be a good solution either.
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.
I see it as analogous to something like http server setup. If you try to bind to a port which is already bound, it throws. Because duplicate registration is startup/setup time it is most likely never throws or throws every time, not flaky or sometimes happening.
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.
Guys we can't break user application just because the otel configuration is wrong or because otel is missing something. Imagine the simple situation when you release a new version on production you then restart all the nodes and suddenly all production is down because the otel has wrong configuration. We can't do this. If otel fails all what should happen is to show user the error but never stop or break the application. The application should work fine in any situation.
|
||
if (api.version != VERSION) { | ||
// All registered APIs must be of the same version exactly | ||
throw new Error( |
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.
ditto
|
||
const myVersionMatch = ownVersion.match(re); | ||
if (!myVersionMatch) { | ||
throw new Error('Cannot parse own version'); |
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.
I think that the whole function should work as typical boolean check and in this case it should return false and maybe just log warning. Otherwise it might stop / break the user system
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.
If it can't parse it's own version that is something that will fail every single time and nothing the user can do about it. In this case I think throwing is the appropriate response since it's a bug that must be fixed. The throw should make this trip in tests and never allow us to release with a version which can't be parsed.
return false; | ||
} | ||
|
||
acceptedVersions.add(version); |
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 it intended to ignore the pre-release part in comparison?
The semver module doesn't do this on default, only if includePrerelease
is specified.
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.
Yes the prerelease part is ignored. A prereleased version should be treated by the comparison as if it was the released version. I may want to release 2.3.1-rc to ensure it works as expected before releasing 2.3.1 and I would not want the check to behave differently for the released v prereleased version.
…pen-telemetry#1772) * feat(auto-instrumentations-node): Expose getting resource detectors The auto instrumentation package provides users with a very easy way to instrument their application, either from the commandline or programatically. Users wishing the configure these instrumentations can also call `getNodeAutoInstrumentations`. This commit also exposes `getResourceDetectorsFromEnv`, so that users configuring or somehow wishing to change the easy to use autoinstrumentation entrypoint can also use the preconfigured resource detectors. Since the autoinstrumentation package sets its exports, this function was previously inaccessible. Usage can look like this: ```js const { getNodeAutoInstrumentations, getResourceDetectorsFromEnv } = require('@opentelemetry/auto-instrumentations-node'); const opentelemetry = require('@opentelemetry/sdk-node'); const sdk = new opentelemetry.NodeSDK({ instrumentations: getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-fs': { enabled: false }, }), resourceDetectors: getResourceDetectorsFromEnv(), }); // use the sdk ``` Workarounds can be found [elsewhere in the opentelemetry repos](https://github.com/open-telemetry/opentelemetry-demo/blob/855bde3588b0fe85e500bec185dc2f311b15f98a/src/paymentservice/opentelemetry.js#L28-L38). These can be fixed once a release is made. Resolves open-telemetry#1531. * style: Align indentation --------- Co-authored-by: Amir Blum <amirgiraffe@gmail.com>
open-telemetry#1792) Better align with the other exports. Follow-up to open-telemetry#1772.
This removes the manual step of the API compatibility version and replaces it with a proper semver check. The expected range is
^${VERSION}
whereVERSION
is the version of the API instance attempting to acquire the global API./cc @Flarna since this was your idea I would appreciate your 👀
THIS IS INCOMPATIBLE WITH PAST API VERSIONS AND IS A HARD BREAKING CHANGE