Skip to content
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

add Events SDK #4629

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open

add Events SDK #4629

wants to merge 26 commits into from

Conversation

martinkuba
Copy link
Contributor

@martinkuba martinkuba commented Apr 11, 2024

Which problem is this PR solving?

This adds an experimental implementation of the Events SDK.

As a related update, I have also updated the Events API with the following:

  • replaced traceId and spanId fields in the Event interface with context field (see spec)
  • added severityNumber field

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated

@martinkuba martinkuba requested a review from a team as a code owner April 11, 2024 19:33
Copy link
Member

@JamieDanielson JamieDanielson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! I added a few non-blocking suggestions to make it easier for someone to try it out. I also added a note about setting a default severityNumber of 9 based on the spec.

const logRecord: LogRecord = {
attributes: attributes,
context: ctx,
severityNumber: event.severityNumber,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the spec it seems we should be setting a default severityNumber of 9 if not provided. Right now it's defaulting to 0 unspecified.

If provided by the user, the SeverityNumber MUST be used to set the Severity Number when emitting the logRecord. If not provided, SeverityNumber MUST be set to SEVERITY_NUMBER_INFO=9.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I have updated to set the SeverityNumber default as well as for timestamp.


// configure global LoggerProvider
const loggerProvider = new LoggerProvider();
loggerProvider.addLogRecordProcessor(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you feel about also showing an OTLP exporter, even just commented out? I'm mostly thinking about how it can be a bit confusing at first to figure out what to use. I realize we should maybe have that in the log example too.

loggerProvider.addLogRecordProcessor(
  new SimpleLogRecordProcessor(new OTLPLogExporter(collectorOptions))
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added it as commented out.

Comment on lines 10 to 11
LogRecord

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LogRecord

Is this intended to be here? Looks like maybe got left over from something else or there is intended to be more words here, not sure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I just realized it's on the log example too ha, probably just copied over.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, copied. I removed it from both, not sure why it was there.

Copy link
Member

@pichlermarc pichlermarc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments, looks good overall 👍

Comment on lines 68 to 69
"@opentelemetry/api-logs": ">=0.39.1",
"@opentelemetry/api-events": ">=0.49.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should depend on these directly and pinned on a specific version. Every minor release can be a breaking change when the version is < 1.0.0.

When users install this and we make a breaking change in the peer-depended packages, it will allow them to install the latest (now incompatible) version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, should we make the change in sdk-logs as well?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL we don't to that in sdk-logs yet. Yes please also change it there 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated sdk-logs as well

): api.EventLogger {
const logger = this._loggerProvider
? this._loggerProvider.getLogger(name, version, options)
: logs.getLogger(name, version, options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see this causing some confusion for some users:

A user might:

  • register the event SDK
  • get an EventLogger ('eventLogger1') from the API
  • register a logs SDK
  • get an EventLogger ('eventLogger2') from the API

eventLogger1 will now not work (it's a no-op), but eventLogger2 will.

While this example seems like something users should not do, it's something that I've seen happening quite often in other parts of the project. The Metrics SDK's MeterProvider#addMetricReader() is one example where we've had a lot of users create instruments, hold on to the SDK's MeterProvider and then register readers after the fact. That did not export instruments created before registration, causing many bug tickets to be opened.

I'd suggest to only allow the explicit case (LoggerProvider passed via the constructor). It's less ergonomic, but there's less room for error. Otherwise #4399 would be required to resolve this situation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done - using the global LoggerProvider is now removed

@@ -0,0 +1,20 @@
{
"name": "events-example",
"version": "0.50.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"version": "0.50.0",
"version": "0.51.0",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

timestamp: event.timestamp || Date.now(),
};

if (event.data) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC data is called payload in the spec. is that something we'd want to align here? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an agreement in the Event SIG that this should be called data. I have opened open-telemetry/opentelemetry-specification#4035 to update the spec.


emit(event: Event) {
const attributes = event.attributes || {};
const ctx = event.context || context.active();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: constant can probably be omitted in favor of adding it directly to the logRecord

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

ConsoleLogRecordExporter,
} = require('@opentelemetry/sdk-logs');

// The Events SDK has a dependency on the Logs SDK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nit: can you keep a consistency in the comments?
some start with capitalized letter and end with period, others don't. Some have a - between sentences on different lines, some don't.

new SimpleLogRecordProcessor(new ConsoleLogRecordExporter())
);
logs.setGlobalLoggerProvider(loggerProvider);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JamieDanielson you made a comment on the other file to add an example for OTLP exporter, do you think one should also exist here?
Or since there is a link to that example right below is enough?


getEventLogger(
name: string,
version?: string | undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to add undefined if you're using ? to mark as optional, since it will already be undefined if you don't pass anything.

Same for the options? below

assert(
spy.calledWith(
sinon.match({
severityNumber: 9,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you use SeverityNumber.INFO here instead of 9? In case the value ever changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

None yet

5 participants