diff --git a/examples/koa/.eslintrc.js b/examples/koa/.eslintrc.js new file mode 100644 index 0000000000..53452072e2 --- /dev/null +++ b/examples/koa/.eslintrc.js @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * + * 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 + * + * https://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. + */ + +'use strict'; + +const baseConfig = require('../../eslint.config'); + +module.exports = { + ...baseConfig, + env: { + node: true, + }, +}; diff --git a/examples/koa/package.json b/examples/koa/package.json index c193ec814f..d7914b7ef7 100644 --- a/examples/koa/package.json +++ b/examples/koa/package.json @@ -4,6 +4,8 @@ "version": "0.1.0", "description": "Example of Koa and @koa/router integration with OpenTelemetry", "scripts": { + "lint": "eslint . --ext=ts,js,mjs", + "lint:fix": "eslint . --ext=ts,js,mjs --fix", "zipkin:server": "cross-env EXPORTER=zipkin ts-node src/server.ts", "zipkin:client": "cross-env EXPORTER=zipkin ts-node src/client.ts", "jaeger:server": "cross-env EXPORTER=jaeger ts-node src/server.ts", @@ -37,6 +39,7 @@ "@opentelemetry/instrumentation": "^0.48.0", "@opentelemetry/instrumentation-http": "^0.48.0", "@opentelemetry/instrumentation-koa": "^0.31.0", + "@opentelemetry/resources": "^1.0.0", "@opentelemetry/sdk-trace-node": "^1.0.0", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/semantic-conventions": "^1.27.0", diff --git a/examples/koa/src/client.ts b/examples/koa/src/client.ts index 40af549da4..705a04e720 100644 --- a/examples/koa/src/client.ts +++ b/examples/koa/src/client.ts @@ -1,29 +1,55 @@ -'use strict'; +/* + * Copyright The OpenTelemetry Authors + * + * 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 + * + * https://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. + */ -import { setupTracing } from "./tracer"; -const tracer = setupTracing('example-koa-client'); import * as api from '@opentelemetry/api'; -import { default as axios } from 'axios'; +import * as axios from 'axios'; +// eslint-disable-next-line import/extensions +import { setupTracing } from './tracer'; + +const tracer = setupTracing('example-koa-client'); -function makeRequest() { +async function makeRequest() { const span = tracer.startSpan('client.makeRequest()', { kind: api.SpanKind.CLIENT, }); - api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), async () => { - try { - const res = await axios.get('http://localhost:8081/run_test'); - span.setStatus({ code: api.SpanStatusCode.OK }); - console.log(res.statusText); - } catch (e) { - if(e instanceof Error) { - span.setStatus({ code: api.SpanStatusCode.ERROR, message: e.message }); + await api.context.with( + api.trace.setSpan(api.ROOT_CONTEXT, span), + async () => { + try { + const res = await axios.get('http://localhost:8081/run_test'); + span.setStatus({ code: api.SpanStatusCode.OK }); + console.log(res.statusText); + } catch (e) { + if (e instanceof Error) { + span.setStatus({ + code: api.SpanStatusCode.ERROR, + message: e.message, + }); + } } + span.end(); + console.log( + 'Sleeping 5 seconds before shutdown to ensure all records are flushed.' + ); + setTimeout(() => { + console.log('Completed.'); + }, 5000); } - span.end(); - console.log('Sleeping 5 seconds before shutdown to ensure all records are flushed.'); - setTimeout(() => { console.log('Completed.'); }, 5000); - }); + ); } -makeRequest(); +makeRequest().catch(err => console.log(err)); diff --git a/examples/koa/src/server.ts b/examples/koa/src/server.ts index f21f77e7bb..91ff6e552f 100644 --- a/examples/koa/src/server.ts +++ b/examples/koa/src/server.ts @@ -1,13 +1,28 @@ -'use strict'; +/* + * Copyright The OpenTelemetry Authors + * + * 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 + * + * https://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. + */ import * as api from '@opentelemetry/api'; -import { setupTracing } from './tracer' -setupTracing('example-koa-server'); // Adding Koa router (if desired) -import * as Router from "@koa/router"; -import * as Koa from "koa" +import * as Router from '@koa/router'; +import * as Koa from 'koa'; +// eslint-disable-next-line import/extensions +import { setupTracing } from './tracer'; +setupTracing('example-koa-server'); // Setup koa const app = new Koa(); @@ -15,7 +30,8 @@ const PORT = 8081; const router = new Router(); // route definitions -router.get('/run_test', runTest) +router + .get('/run_test', runTest) .get('/post/new', addPost) .get('/post/:id', showNewPost); @@ -26,7 +42,7 @@ async function setUp() { /** * Router functions: list, add, or show posts -*/ + */ const posts = ['post 0', 'post 1', 'post 2']; function addPost(ctx: Koa.Context) { @@ -34,7 +50,7 @@ function addPost(ctx: Koa.Context) { posts.push(`post ${newPostId}`); const currentSpan = api.trace.getSpan(api.context.active()); currentSpan?.addEvent('Added post'); - currentSpan?.setAttribute('post.id', newPostId) + currentSpan?.setAttribute('post.id', newPostId); ctx.body = `Added post: ${posts[posts.length - 1]}`; ctx.redirect('/post/3'); } @@ -45,14 +61,16 @@ async function showNewPost(ctx: Koa.Context) { const post = posts[id]; if (!post) ctx.throw(404, 'Invalid post id'); const syntheticDelay = 500; - await new Promise((r) => setTimeout(r, syntheticDelay)); + await new Promise(r => { + setTimeout(r, syntheticDelay); + }); ctx.body = post; } function runTest(ctx: Koa.Context) { console.log('runTest'); const currentSpan = api.trace.getSpan(api.context.active()); - if (currentSpan){ + if (currentSpan) { const { traceId } = currentSpan.spanContext(); console.log(`traceid: ${traceId}`); console.log(`Jaeger URL: http://localhost:16686/trace/${traceId}`); @@ -62,14 +80,15 @@ function runTest(ctx: Koa.Context) { } } -async function noOp(ctx: Koa.Context, next: Koa.Next) { +function noOp(ctx: Koa.Context, next: Koa.Next) { console.log('Sample basic koa middleware'); const syntheticDelay = 100; - await new Promise((r) => setTimeout(r, syntheticDelay)); - next(); + setTimeout(next, syntheticDelay); } -setUp().then(() => { - app.listen(PORT); - console.log(`Listening on http://localhost:${PORT}`); -}); +setUp() + .then(() => { + app.listen(PORT); + console.log(`Listening on http://localhost:${PORT}`); + }) + .catch(err => console.log(err)); diff --git a/examples/koa/src/tracer.ts b/examples/koa/src/tracer.ts index 06d8b56944..7816edc706 100644 --- a/examples/koa/src/tracer.ts +++ b/examples/koa/src/tracer.ts @@ -1,4 +1,18 @@ -'use strict'; +/* + * Copyright The OpenTelemetry Authors + * + * 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 + * + * https://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. + */ import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; @@ -10,10 +24,11 @@ import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { JaegerExporter } from '@opentelemetry/exporter-jaeger'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; import { Resource } from '@opentelemetry/resources'; -import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions' +import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const EXPORTER = process.env.EXPORTER || ''; +// eslint-disable-next-line import/prefer-default-export export const setupTracing = (serviceName: string) => { let exporter; if (EXPORTER === 'jaeger') { @@ -24,18 +39,13 @@ export const setupTracing = (serviceName: string) => { const provider = new NodeTracerProvider({ resource: new Resource({ - [ATTR_SERVICE_NAME]: serviceName + [ATTR_SERVICE_NAME]: serviceName, }), - spanProcessors: [ - new SimpleSpanProcessor(exporter), - ], + spanProcessors: [new SimpleSpanProcessor(exporter)], }); registerInstrumentations({ - instrumentations: [ - new KoaInstrumentation(), - new HttpInstrumentation(), - ], + instrumentations: [new KoaInstrumentation(), new HttpInstrumentation()], tracerProvider: provider, });