From cbc00cf51bdbd0a744e1ae43f46f58bdd83a0f6d Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 26 Jun 2025 11:30:54 -0700 Subject: [PATCH] chore(examples): lint examples/mysql using shared top-level eslint config Refs: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2891 --- examples/mysql/.eslintrc.js | 26 ++++++ examples/mysql/package.json | 4 + examples/mysql/src/client.ts | 175 +++++++++++++++++++++-------------- examples/mysql/src/server.ts | 52 +++++++---- examples/mysql/src/tracer.ts | 41 +++++--- 5 files changed, 196 insertions(+), 102 deletions(-) create mode 100644 examples/mysql/.eslintrc.js diff --git a/examples/mysql/.eslintrc.js b/examples/mysql/.eslintrc.js new file mode 100644 index 0000000000..53452072e2 --- /dev/null +++ b/examples/mysql/.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/mysql/package.json b/examples/mysql/package.json index 4ad6138d24..e8484bf1d0 100644 --- a/examples/mysql/package.json +++ b/examples/mysql/package.json @@ -5,6 +5,8 @@ "description": "Example of mysql integration with OpenTelemetry", "main": "index.js", "scripts": { + "lint": "eslint . --ext=ts,js,mjs", + "lint:fix": "eslint . --ext=ts,js,mjs --fix", "docker:start": "docker run -p 3306:3306 --name example-mysql -e MYSQL_ROOT_PASSWORD=secret -d mysql:5.7", "docker:stop": "docker stop example-mysql && docker rm example-mysql", "zipkin:server": "cross-env EXPORTER=zipkin ts-node src/server.ts", @@ -35,6 +37,8 @@ "@opentelemetry/instrumentation": "^0.48.0", "@opentelemetry/instrumentation-http": "^0.48.0", "@opentelemetry/instrumentation-mysql": "^0.31.0", + "@opentelemetry/resources": "^1.0.0", + "@opentelemetry/sdk-metrics": "^1.0.0", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/sdk-trace-node": "^1.0.0", "@opentelemetry/semantic-conventions": "^1.27.0", diff --git a/examples/mysql/src/client.ts b/examples/mysql/src/client.ts index de80b7bc11..d317a30c04 100644 --- a/examples/mysql/src/client.ts +++ b/examples/mysql/src/client.ts @@ -1,9 +1,25 @@ -'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"; -const tracer = setupTracing('example-mysql-client'); import * as http from 'http'; +// eslint-disable-next-line import/extensions +import { setupTracing } from './tracer'; + +const tracer = setupTracing('example-mysql-client'); /** A function which makes requests and handles response. */ function makeRequest() { @@ -17,90 +33,109 @@ function makeRequest() { api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), () => { queries += 1; - http.get({ - host: 'localhost', - port: 8080, - path: '/connection/query', - }, (response) => { - const body: any[] = []; - response.on('data', (chunk) => body.push(chunk)); - response.on('end', () => { - responses += 1; - console.log(body.toString()); - if (responses === queries) span.end(); - }); - }); + http.get( + { + host: 'localhost', + port: 8080, + path: '/connection/query', + }, + response => { + const body: any[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + responses += 1; + console.log(body.toString()); + if (responses === queries) span.end(); + }); + } + ); }); api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), () => { queries += 1; - http.get({ - host: 'localhost', - port: 8080, - path: '/pool/query', - }, (response) => { - const body: any[] = []; - response.on('data', (chunk) => body.push(chunk)); - response.on('end', () => { - responses += 1; - console.log(body.toString()); - if (responses === queries) span.end(); - }); - }); + http.get( + { + host: 'localhost', + port: 8080, + path: '/pool/query', + }, + response => { + const body: any[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + responses += 1; + console.log(body.toString()); + if (responses === queries) span.end(); + }); + } + ); }); api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), () => { queries += 1; - http.get({ - host: 'localhost', - port: 8080, - path: '/pool/query-with-2-connections', - }, (response) => { - const body: any[] = []; - response.on('data', (chunk) => body.push(chunk)); - response.on('end', () => { - responses += 1; - console.log(body.toString()); - if (responses === queries) span.end(); - }); - }); + http.get( + { + host: 'localhost', + port: 8080, + path: '/pool/query-with-2-connections', + }, + response => { + const body: any[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + responses += 1; + console.log(body.toString()); + if (responses === queries) span.end(); + }); + } + ); }); api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), () => { queries += 1; - http.get({ - host: 'localhost', - port: 8080, - path: '/pool/query-2-pools', - }, (response) => { - const body: any[] = []; - response.on('data', (chunk) => body.push(chunk)); - response.on('end', () => { - responses += 1; - console.log(body.toString()); - if (responses === queries) span.end(); - }); - }); + http.get( + { + host: 'localhost', + port: 8080, + path: '/pool/query-2-pools', + }, + response => { + const body: any[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + responses += 1; + console.log(body.toString()); + if (responses === queries) span.end(); + }); + } + ); }); api.context.with(api.trace.setSpan(api.ROOT_CONTEXT, span), () => { queries += 1; - http.get({ - host: 'localhost', - port: 8080, - path: '/cluster/query', - }, (response) => { - const body: any[] = []; - response.on('data', (chunk) => body.push(chunk)); - response.on('end', () => { - responses += 1; - console.log(body.toString()); - if (responses === queries) span.end(); - }); - }); + http.get( + { + host: 'localhost', + port: 8080, + path: '/cluster/query', + }, + response => { + const body: any[] = []; + response.on('data', chunk => body.push(chunk)); + response.on('end', () => { + responses += 1; + console.log(body.toString()); + if (responses === queries) span.end(); + }); + } + ); }); // The process must live for at least the interval past any traces that // must be exported, or some risk being lost if they are recorded after the // last export. - console.log('Sleeping 5 seconds before shutdown to ensure all records are flushed.'); - setTimeout(() => { console.log('Completed.'); }, 5000); + console.log( + 'Sleeping 5 seconds before shutdown to ensure all records are flushed.' + ); + setTimeout(() => { + console.log('Completed.'); + }, 5000); } makeRequest(); diff --git a/examples/mysql/src/server.ts b/examples/mysql/src/server.ts index 180224e2c7..513e45d6fd 100644 --- a/examples/mysql/src/server.ts +++ b/examples/mysql/src/server.ts @@ -1,13 +1,27 @@ -'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. + */ -// eslint-disable-next-line import/order -import { setupTracing } from "./tracer"; -setupTracing('example-mysql-server'); import * as api from '@opentelemetry/api'; -import * as mysql from 'mysql' +import * as mysql from 'mysql'; import * as http from 'http'; -import { MysqlError } from "mysql"; -import { PoolConnection } from "mysql"; +import { MysqlError, PoolConnection } from 'mysql'; +// eslint-disable-next-line import/extensions +import { setupTracing } from './tracer'; + +setupTracing('example-mysql-server'); const pool = mysql.createPool({ host: 'localhost', @@ -19,7 +33,7 @@ const pool2 = mysql.createPool({ host: 'localhost', user: 'root', password: 'secret', - database: 'db_test' //this db is created by init.sql + database: 'db_test', // this db is created by init.sql }); const connection = mysql.createConnection({ @@ -48,27 +62,23 @@ function startServer(port: number | undefined) { /** A function which handles requests and send response. */ function handleRequest(request: any, response: any) { - const currentSpan = api.trace.getSpan(api.context.active()) + const currentSpan = api.trace.getSpan(api.context.active()); // display traceid in the terminal const traceId = currentSpan?.spanContext().traceId; console.log(`traceid: ${traceId}`); console.log(`Zipkin URL: http://localhost:9411/zipkin/traces/${traceId}`); try { const body = []; - request.on('error', - (err: any) => console.log(err) - ); - request.on('data', - (chunk: any) => body.push(chunk) - ); + request.on('error', (err: any) => console.log(err)); + request.on('data', (chunk: any) => body.push(chunk)); request.on('end', () => { if (request.url === '/connection/query') { handleConnectionQuery(response); } else if (request.url === '/pool/query') { handlePoolQuery(response); - } else if(request.url === '/pool/query-with-2-connections') { + } else if (request.url === '/pool/query-with-2-connections') { handlePoolwith2ConnectionsQuery(response); - } else if(request.url === '/pool/query-2-pools') { + } else if (request.url === '/pool/query-2-pools') { handle2PoolsQuery(response); } else if (request.url === '/cluster/query') { handleClusterQuery(response); @@ -143,7 +153,7 @@ function handle2PoolsQuery(response: any) { }); } -function handlePoolwith2ConnectionsQuery(response: any){ +function handlePoolwith2ConnectionsQuery(response: any) { const query = 'SELECT 1 + 1 as pool_2_connections_solution'; pool.getConnection((connErr: MysqlError, conn: PoolConnection) => { if (connErr) { @@ -159,7 +169,7 @@ function handlePoolwith2ConnectionsQuery(response: any){ const res = results[0].pool_2_connections_solution; response.write(`${query} 1: ${res}`); - //finish with the 1st connection. create another one, then end() both. + // finish with the 1st connection. create another one, then end() both. const query2 = `SELECT ${res} + ${res} as pool_2_connections_solution`; pool.getConnection((connErr: MysqlError, conn2: PoolConnection) => { if (connErr) { @@ -172,7 +182,9 @@ function handlePoolwith2ConnectionsQuery(response: any){ console.log('Error code 2:', err.code); response.end(err.message); } else { - response.end(`${query2} 2: ${results[0].pool_2_connections_solution}`); + response.end( + `${query2} 2: ${results[0].pool_2_connections_solution}` + ); pool.end(); } }); diff --git a/examples/mysql/src/tracer.ts b/examples/mysql/src/tracer.ts index c552e33e3e..f90c0c469d 100644 --- a/examples/mysql/src/tracer.ts +++ b/examples/mysql/src/tracer.ts @@ -1,8 +1,25 @@ -'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 opentelemetry from '@opentelemetry/api'; import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; -import { SimpleSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base'; +import { + SimpleSpanProcessor, + SpanProcessor, +} from '@opentelemetry/sdk-trace-base'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; @@ -13,13 +30,16 @@ import { MeterProvider, PeriodicExportingMetricReader, } from '@opentelemetry/sdk-metrics'; -const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc'); + +const { + OTLPMetricExporter, +} = require('@opentelemetry/exporter-metrics-otlp-grpc'); const EXPORTER = process.env.EXPORTER || ''; +// eslint-disable-next-line import/prefer-default-export export const setupTracing = (serviceName: string) => { - - //metrics: + // metrics: const metricExporter = new OTLPMetricExporter(); const metricReader = new PeriodicExportingMetricReader({ exporter: metricExporter, @@ -30,7 +50,7 @@ export const setupTracing = (serviceName: string) => { readers: [metricReader], }); - //traces: + // traces: const spanProcessors: SpanProcessor[] = []; if (EXPORTER.toLowerCase().startsWith('z')) { @@ -48,12 +68,9 @@ export const setupTracing = (serviceName: string) => { tracerProvider.register(); registerInstrumentations({ - instrumentations: [ - new HttpInstrumentation(), - new MySQLInstrumentation(), - ], - tracerProvider: tracerProvider, - meterProvider: meterProvider, + instrumentations: [new HttpInstrumentation(), new MySQLInstrumentation()], + tracerProvider, + meterProvider, }); return opentelemetry.trace.getTracer('mysql-example');