-
Notifications
You must be signed in to change notification settings - Fork 227
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: add support for OTel context propagation and harmonized spans (v3.x) #1659
Changes from 41 commits
0d9c0b2
4f3daa9
80d8b65
cbd5992
75acbab
bb6cf85
5cddaed
d523b1f
fbe29a2
197a214
a36cfce
5c4fef6
b58557d
4b7cf0c
45047c7
3995fd0
f2f8f57
4a2a79e
bb815d3
5d60ff3
f8a5c09
d21480d
fe4947d
568add9
5243ea9
8dd13f8
60c70a8
57c1673
0a3b9a6
bc95037
02b395b
a3d66c2
a1870ac
50c8f74
90f9ead
4ce3fc4
8e18826
569d744
886c0ee
8b7e0a9
4df6be6
83830d6
094f08d
a713a2e
58c979a
171c8f9
2b4dd6e
7b13da5
f66cfcd
2e09a3d
50bd1bf
0e7e5da
a287386
68335e5
0f2dc41
1ba495a
49b0bc3
12f400d
febcd16
a471875
a37194d
9ec1fdf
5f33931
f167885
feeccf1
b218d5f
2471c16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,20 @@ | ||
/*! | ||
* Copyright 2020 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
// Copyright 2020-2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
// This is a generated sample, using the typeless sample bot. Please | ||
// look for the source TypeScript sample (.ts) for modifications. | ||
'use strict'; | ||
|
||
/** | ||
* This sample demonstrates how to add OpenTelemetry tracing to the | ||
|
@@ -22,8 +24,6 @@ | |
* at https://cloud.google.com/pubsub/docs. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
// sample-metadata: | ||
// title: OpenTelemetry Tracing | ||
// description: Demonstrates how to enable OpenTelemetry tracing in | ||
|
@@ -32,103 +32,107 @@ | |
|
||
const SUBSCRIBER_TIMEOUT = 10; | ||
|
||
// [START opentelemetry_tracing] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we should standardize on this region tag at some point before submitting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think the person who originally made this just came up with one? I think maybe it deserves several samples, e.g. one for Cloud Trace, another for console output, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we shouldn't do console output and just focus on Cloud Trace as the default sample (since that's also what our open telemetry team's documentation points to). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do think that's the primary thing we want to help people with, 'cause it's probably what they want to do. But I do think we ought to at least e.g. have a Medium article talking about how to output to console, Grafana, etc. Those will be useful to people too. |
||
/** | ||
* TODO(developer): Uncomment these variables before running the sample. | ||
*/ | ||
// const topicNameOrId = 'YOUR_TOPIC_OR_ID'; | ||
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_OR_ID'; | ||
// const data = 'Hello, world!"; | ||
|
||
// Imports the Google Cloud client library | ||
const {PubSub} = require('@google-cloud/pubsub'); | ||
|
||
// Imports the OpenTelemetry API | ||
const otel = require('@opentelemetry/sdk-trace-node'); | ||
const {diag, DiagConsoleLogger, DiagLogLevel} = require('@opentelemetry/api'); | ||
const {NodeTracerProvider} = otel; | ||
const { | ||
SimpleSpanProcessor, | ||
ConsoleSpanExporter, | ||
} = require('@opentelemetry/sdk-trace-base'); | ||
|
||
const {Resource} = require('@opentelemetry/resources'); | ||
const { | ||
SemanticResourceAttributes, | ||
} = require('@opentelemetry/semantic-conventions'); | ||
|
||
// Enable the diagnostic logger for OpenTelemetry | ||
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); | ||
|
||
// Log spans out to the console for this test | ||
const exporter = new ConsoleSpanExporter(); | ||
|
||
// Build a tracer provider and a span processor to do | ||
// something with the spans we're generating. | ||
const provider = new NodeTracerProvider({ | ||
resource: new Resource({ | ||
[SemanticResourceAttributes.SERVICE_NAME]: 'otel example', | ||
}), | ||
}); | ||
const processor = new SimpleSpanProcessor(exporter); | ||
provider.addSpanProcessor(processor); | ||
provider.register(); | ||
|
||
// Creates a client; cache this for further use. | ||
const pubSubClient = new PubSub(); | ||
|
||
async function publishMessage(topicNameOrId, data) { | ||
// Publishes the message as a string, e.g. "Hello, world!" or JSON.stringify(someObject) | ||
const dataBuffer = Buffer.from(data); | ||
const messageId = await pubSubClient | ||
.topic(topicNameOrId) | ||
.publishMessage({data: dataBuffer}); | ||
console.log(`Message ${messageId} published.`); | ||
} | ||
|
||
async function subscriptionListen(subscriptionNameOrId) { | ||
hongalex marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Message handler for subscriber | ||
const messageHandler = message => { | ||
console.log(`Message ${message.id} received.`); | ||
message.ack(); | ||
|
||
// Ensure that all spans got flushed by the exporter | ||
console.log('Cleaning up OpenTelemetry exporter...'); | ||
exporter.shutdown().then(() => { | ||
// Cleaned up exporter. | ||
process.exit(0); | ||
}); | ||
}; | ||
|
||
const errorHandler = error => { | ||
console.log('Received error:', error); | ||
|
||
console.log('Cleaning up OpenTelemetry exporter...'); | ||
exporter.shutdown().then(() => { | ||
// Cleaned up exporter. | ||
process.exit(0); | ||
}); | ||
}; | ||
|
||
// Listens for new messages from the topic | ||
pubSubClient.subscription(subscriptionNameOrId).on('message', messageHandler); | ||
pubSubClient.subscription(subscriptionNameOrId).on('error', errorHandler); | ||
|
||
// Wait a bit for the subscription to receive messages. | ||
// For the sample only. | ||
setTimeout(() => { | ||
pubSubClient.subscription(subscriptionNameOrId).removeAllListeners(); | ||
}, SUBSCRIBER_TIMEOUT * 1000); | ||
} | ||
// [END opentelemetry_tracing] | ||
|
||
function main( | ||
topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID', | ||
subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID', | ||
data = 'Hello, world!' | ||
) { | ||
// [START opentelemetry_tracing] | ||
/** | ||
* TODO(developer): Uncomment these variables before running the sample. | ||
*/ | ||
// const topicNameOrId = 'YOUR_TOPIC_OR_ID'; | ||
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_OR_ID'; | ||
// const data = 'Hello, world!"; | ||
|
||
// Imports the Google Cloud client library | ||
const {PubSub} = require('@google-cloud/pubsub'); | ||
|
||
// Imports the OpenTelemetry API | ||
const opentelemetry = require('@opentelemetry/api'); | ||
|
||
// Imports the OpenTelemetry span handlers and exporter | ||
const { | ||
SimpleSpanProcessor, | ||
BasicTracerProvider, | ||
ConsoleSpanExporter, | ||
} = require('@opentelemetry/tracing'); | ||
|
||
// Set up span processing and specify the console as the span exporter | ||
const provider = new BasicTracerProvider(); | ||
const exporter = new ConsoleSpanExporter(); | ||
provider.addSpanProcessor(new SimpleSpanProcessor(exporter)); | ||
// Enable the diagnostic logger for Opentelemetry | ||
opentelemetry.diag.setLogger( | ||
new opentelemetry.DiagConsoleLogger(), | ||
opentelemetry.DiagLogLevel.INFO | ||
); | ||
|
||
provider.register(); | ||
|
||
// OpenTelemetry tracing is an optional feature and can be enabled by setting | ||
// enableOpenTelemetryTracing as a publisher or subscriber option | ||
const enableOpenTelemetryTracing = { | ||
enableOpenTelemetryTracing: true, | ||
}; | ||
|
||
// Creates a client; cache this for further use | ||
const pubSubClient = new PubSub(); | ||
|
||
async function publishMessage() { | ||
// Publishes the message as a string, e.g. "Hello, world!" or JSON.stringify(someObject) | ||
const dataBuffer = Buffer.from(data); | ||
const messageId = await pubSubClient | ||
.topic(topicNameOrId, enableOpenTelemetryTracing) | ||
.publish(dataBuffer); | ||
console.log(`Message ${messageId} published.`); | ||
} | ||
|
||
async function subscriptionListen() { | ||
// Message handler for subscriber | ||
const messageHandler = message => { | ||
console.log(`Message ${message.id} received.`); | ||
message.ack(); | ||
|
||
// Ensure that all spans got flushed by the exporter | ||
console.log('Cleaning up Opentelemetry exporter...'); | ||
exporter.shutdown().then(() => { | ||
// Cleaned up exporter. | ||
process.exit(0); | ||
}); | ||
}; | ||
|
||
const errorHandler = error => { | ||
console.log('Received error:', error); | ||
|
||
console.log('Cleaning up Opentelemetry exporter...'); | ||
exporter.shutdown().then(() => { | ||
// Cleaned up exporter. | ||
process.exit(0); | ||
}); | ||
}; | ||
|
||
// Listens for new messages from the topic | ||
pubSubClient | ||
.subscription(subscriptionNameOrId, enableOpenTelemetryTracing) | ||
.on('message', messageHandler); | ||
pubSubClient | ||
.subscription(subscriptionNameOrId, enableOpenTelemetryTracing) | ||
.on('error', errorHandler); | ||
|
||
setTimeout(() => { | ||
pubSubClient | ||
.subscription(subscriptionNameOrId, enableOpenTelemetryTracing) | ||
.removeAllListeners(); | ||
}, SUBSCRIBER_TIMEOUT * 1000); | ||
} | ||
|
||
publishMessage().then(subscriptionListen()); | ||
// [END opentelemetry_tracing] | ||
publishMessage(topicNameOrId, data) | ||
.then(() => subscriptionListen(subscriptionNameOrId)) | ||
.catch(err => { | ||
console.error(err.message); | ||
process.exitCode = 1; | ||
}); | ||
} | ||
|
||
main(...process.argv.slice(2)); |
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 particular reason these are locked down from
^
?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, it had to do with Node 12 compatibility. I found that there were some semver issues, in practice, though I'll be revisiting this for the 4.x version of the PR, so I'll probably recheck these for 3.x too.