diff --git a/index.json b/index.json index 4aef2f15..fa407af8 100644 --- a/index.json +++ b/index.json @@ -4,7 +4,7 @@ "title": "Laravel", "tags": ["php", "laravel"], "description": "", - "content": " Introduction Requirements Installation composer install source Fields Sample log entry Expected fields References Introduction This package is in the form of Illuminate Database Connector Wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help with later making database optimization decisions, after those statements are examined from the database server\u0026rsquo;s logs.\nRequirements It requires php 8 \u0026amp; above\nInstallation This middleware can be installed by any of the following:\nComposer composer require google/sqlcommenter-laravel Source git clone https://github.com/google/sqlcommenter.git # Add the following to composer.json \u0026#34;repositories\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;path\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;/full/or/relative/path/to/sqlcommenter/php/sqlcommenter-php/packages/sqlcommenter-laravel/\u0026#34; } ] composer require \u0026#34;google/sqlcommenter-laravel\u0026#34; Enabling it Publish the config file from library to into laravel app using below command\nphp artisan vendor:publish --provider=\u0026#34;Google\\GoogleSqlCommenterLaravel\\GoogleSqlCommenterServiceProvider\u0026#34; Add the following class above Illuminate\\Database\\DatabaseServiceProvider::class, in config/app.php\n\u0026#39;providers\u0026#39; =\u0026gt; [ ... Google\\GoogleSqlCommenterLaravel\\Database\\DatabaseServiceProvider::class, Illuminate\\Database\\DatabaseServiceProvider::class, ... ] Fields In the database server logs, the comment\u0026rsquo;s fields are:\n comma separated key-value pairs e.g. controller='index' values are SQL escaped i.e. key='value' URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. so should be URL-unquoted when being consumed Sample log entry After making a request into the middleware-enabled polls web-app.\n2022-04-29 13:59:39.922 IST [27935] LOG: duration: 0.012 ms execute pdo_stmt_00000003: Select * from users /*framework=\u0026#39;laravel-9.7.0\u0026#39;,controller=\u0026#39;UserController\u0026#39;,action=\u0026#39;index\u0026#39;,route=\u0026#39;%%2Fapi%%2Ftest\u0026#39;,db_driver=\u0026#39;pgsql\u0026#39;,traceparent=\u0026#39;00-1cd60708968a61e942b5dacc2d4a5473-7534abe7ed36ce35-01\u0026#39;*/ Expected Fields Field Included by default? Description action ✔ The application namespace of the matching URL pattern in your routes/api.php controller ✔ The name of the matching URL pattern as described in your routes/api.php db_driver ✔ The name of the php database engine framework ✔ The word \u0026ldquo;laravel\u0026rdquo; and the version of laravel being used route ✔ The route of the matching URL pattern as described in your routes/api.php traceparent ✔ The W3C TraceContext.Traceparent field of the OpenTelemetry trace End to end examples Examples are based upon the sample\nSource code # config/google_sqlcommenter.php \u0026lt;?php return [ /* | | These parameters enables/disable whether the specified info can be | appended to the query */ \u0026#39;include\u0026#39; =\u0026gt; [ \u0026#39;framework\u0026#39; =\u0026gt; true, \u0026#39;controller\u0026#39; =\u0026gt; true, \u0026#39;route\u0026#39; =\u0026gt; true, \u0026#39;db_driver\u0026#39; =\u0026gt; true, \u0026#39;opentelemetry\u0026#39; =\u0026gt; true, \u0026#39;action\u0026#39; =\u0026gt; true, ] ]; From the command line, we run the laravel development server in one terminal:\nphp artisan serve And we use curl to make an HTTP request in another:\ncurl http://127.0.0.1:8000/user/select Results Examining our Postgresql server logs, with the various options\n2022-04-29 13:59:39.922 IST [27935] LOG: duration: 0.012 ms execute pdo_stmt_00000003: Select 1/*framework=\u0026#39;laravel-9.7.0\u0026#39;,controller=\u0026#39;UserController\u0026#39;,action=\u0026#39;index\u0026#39;,route=\u0026#39;%%2Fapi%%2Ftest\u0026#39;,db_driver=\u0026#39;pgsql\u0026#39;, traceparent=\u0026#39;00-1cd60708968a61e942b5dacc2d4a5473-7534abe7ed36ce35-01\u0026#39;*/ References Resource URL laravel https://laravel.com/docs/5.1/quickstart OpenTelemetry https://opentelemetry.io opentelemetry-php https://github.com/open-telemetry/opentelemetry-php sqlcommenter on Github https://github.com/google/sqlcommenter " + "content": " Introduction Requirements Installation composer install source Fields Sample log entry Expected fields References Introduction This package is in the form of Illuminate Database Connector Wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help with later making database optimization decisions, after examining the statements.\nRequirements It requires php 8 \u0026amp; above.\nInstallation At present, we can install sqlcommenter-laravel from source.\nThis middleware can be installed by one of the following methods:\nComposer composer require google/sqlcommenter-laravel Source git clone https://github.com/google/sqlcommenter.git # Add the following to composer.json \u0026#34;repositories\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;path\u0026#34;, \u0026#34;url\u0026#34;: \u0026#34;/full/or/relative/path/to/sqlcommenter/php/sqlcommenter-php/packages/sqlcommenter-laravel/\u0026#34; } ] composer require \u0026#34;google/sqlcommenter-laravel\u0026#34; Enabling it Publish the config file from library to into laravel app using below command\nphp artisan vendor:publish --provider=\u0026#34;Google\\GoogleSqlCommenterLaravel\\GoogleSqlCommenterServiceProvider\u0026#34; Add the following class above Illuminate\\Database\\DatabaseServiceProvider::class, in config/app.php\n\u0026#39;providers\u0026#39; =\u0026gt; [ ... Google\\GoogleSqlCommenterLaravel\\Database\\DatabaseServiceProvider::class, Illuminate\\Database\\DatabaseServiceProvider::class, ... ] Fields SQL Statements generated are appended with a comment having fields:\n comma separated key-value pairs e.g. controller='index'. values are SQL escaped i.e. key='value'. URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. So, should be URL-unquoted when being consumed. Sample log entry After making requests to the sample middleware-enabled polls web-app, we can see logs like:\n2022-04-29 13:59:39.922 IST [27935] LOG: duration: 0.012 ms execute pdo_stmt_00000003: Select * from users /*framework=\u0026#39;laravel-9.7.0\u0026#39;,controller=\u0026#39;UserController\u0026#39;,action=\u0026#39;index\u0026#39;,route=\u0026#39;%%2Fapi%%2Ftest\u0026#39;,db_driver=\u0026#39;pgsql\u0026#39;,traceparent=\u0026#39;00-1cd60708968a61e942b5dacc2d4a5473-7534abe7ed36ce35-01\u0026#39;*/ Expected Fields Field Included by default? Description action ✔ The application namespace of the matching URL pattern in your routes/api.php controller ✔ The name of the matching URL pattern as described in your routes/api.php db_driver ✔ The name of the php database engine framework ✔ The word \u0026ldquo;laravel\u0026rdquo; and the version of laravel being used route ✔ The route of the matching URL pattern as described in your routes/api.php traceparent ✔ The W3C TraceContext.Traceparent field of the OpenTelemetry trace End to end examples Examples are based upon the sample app.\nSource code # config/google_sqlcommenter.php \u0026lt;?php return [ /* | | These parameters enables/disable whether the specified info can be | appended to the query */ \u0026#39;include\u0026#39; =\u0026gt; [ \u0026#39;framework\u0026#39; =\u0026gt; true, \u0026#39;controller\u0026#39; =\u0026gt; true, \u0026#39;route\u0026#39; =\u0026gt; true, \u0026#39;db_driver\u0026#39; =\u0026gt; true, \u0026#39;opentelemetry\u0026#39; =\u0026gt; true, \u0026#39;action\u0026#39; =\u0026gt; true, ] ]; From the command line, we run the laravel development server in one terminal:\nphp artisan serve And we use curl to make an HTTP request in another:\ncurl http://127.0.0.1:8000/user/select Results Examining our Postgresql server logs, with the various options\n2022-04-29 13:59:39.922 IST [27935] LOG: duration: 0.012 ms execute pdo_stmt_00000003: Select 1/*framework=\u0026#39;laravel-9.7.0\u0026#39;,controller=\u0026#39;UserController\u0026#39;,action=\u0026#39;index\u0026#39;,route=\u0026#39;%%2Fapi%%2Ftest\u0026#39;,db_driver=\u0026#39;pgsql\u0026#39;, traceparent=\u0026#39;00-1cd60708968a61e942b5dacc2d4a5473-7534abe7ed36ce35-01\u0026#39;*/ References Resource URL laravel https://laravel.com/docs/5.1/quickstart OpenTelemetry https://opentelemetry.io opentelemetry-php https://github.com/open-telemetry/opentelemetry-php sqlcommenter on Github https://github.com/google/sqlcommenter " }, { "uri": "https://google.github.io/sqlcommenter/ruby/rails/", @@ -39,14 +39,14 @@ "title": "Knex.js", "tags": ["knex", "knex.js", "query-builder", "node", "node.js", "express", "express.js"], "description": "", - "content": " Introduction Requirements Installation Manually Package manager Usage Plain knex wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Knex.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex.js.\nBesides plain knex.js wrapping, we also provide a wrapper for the following frameworks:\n Requirements Name Resource Knex.js https://knexjs.org/ Node.js https://nodejs.org/ Installation We can add integration into our applications in the following ways:\nManually Please read installing sqlcommenter-nodejs from source\nPackage manager Add to your package.json the dependency { \u0026#34;@google-cloud/sqlcommenter-knex\u0026#34;: \u0026#34;*\u0026#34; } and then run npm install to get the latest version or npm install @google-cloud/sqlcommenter-knex --save\nUsage Plain knex wrapper const {wrapMainKnex} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); wrapMainKnex(Knex); // Now you can create the knex client. const knex = Knex(options); Express middleware This wrapper/middleware can be used as is or better with express.js const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); const app = require(\u0026#39;express\u0026#39;)(); // This is the important step where we set the middleware. app.use(wrapMainKnexAsMiddleware(Knex)); // Now you can create the knex client. const knex = Knex(options); \nFields In the database server logs, the comment\u0026rsquo;s fields are:\n comma separated key-value pairs e.g. route='%5Epolls/%24' values are SQL escaped i.e. key='value' URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. so should be URL-unquoted Field Format Description Example db_driver \u0026lt;database_driver\u0026gt;:\u0026lt;version\u0026gt; URL quoted name and version of the database driver db_driver='knex%3A0.16.5' route \u0026lt;the route used\u0026gt; URL quoted route used to match the express.js controller route='%5E%2Fpolls%2F traceparent \u0026lt;traceparent header\u0026gt; URL quoted W3C traceparent header traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01' tracestate \u0026lt;tracestate header\u0026gt; URL quoted W3C tracestate header tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE' Options When creating the middleware, one can optionally configure the injected comments by passing in the include and options objects:\nwrapMainKnexAsMiddleware(Knex, include={...}, options={...}); include config A map of values to be optionally included in the SQL comments.\n Field On by default db_driver \u0026#10060; route \u0026#10004; traceparent \u0026#10060; tracestate \u0026#10060; options config A configuration object specifying where to collect trace data from. Accepted fields are: TraceProvider: Should be either OpenCensus or OpenTelemetry, indicating which library to collect trace context from.\n Field Possible values TraceProvider OpenCensus or OpenTelemetry Options examples trace attributes route db_driver all set wrapMainKnexAsMiddleware( Knex, include={ traceparent: true, tracestate: true }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); wrapMainKnexAsMiddleware(Knex, include={route: true}); wrapMainKnexAsMiddleware(Knex, include={db_driver: true}); // Manually set all the variables. wrapMainKnexAsMiddleware( Knex, include={ db_driver: true, route: true, traceparent: true, tracestate: true, }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); End to end examples Check out a full express + opentelemetry example here.\nSource code With OpenCensus With OpenTelemetry With Route With DB Driver With All Options Set // In file app.js. const tracing = require(\u0026#39;@opencensus/nodejs\u0026#39;); const {B3Format} = require(\u0026#39;@opencensus/propagation-b3\u0026#39;); const {ZipkinTraceExporter} = require(\u0026#39;@opencensus/exporter-zipkin\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const exporter = new ZipkinTraceExporter({ url: process.env.ZIPKIN_TRACE_URL || \u0026#39;localhost://9411/api/v2/spans\u0026#39;, serviceName: \u0026#39;trace-542\u0026#39; }); const b3 = new B3Format(); const traceOptions = { samplingRate: 1, // Always sample propagation: b3, exporter: exporter }; // start tracing tracing.start(traceOptions); const knexOptions = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with trace attributes app.use(wrapMainKnexAsMiddleware(Knex, { traceparent: true, tracestate: true, route: false })); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const express = require(\u0026#34;express\u0026#34;); const Knex = require(\u0026#34;knex\u0026#34;); const { wrapMainKnexAsMiddleware } = require(\u0026#34;@google-cloud/sqlcommenter-knex\u0026#34;); const knexOptions = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapMainKnexAsMiddleware( Knex, { traceparent: true, tracestate: true, // Optional db_driver: false, route: false, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const options = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(options); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with route app.use(wrapMainKnexAsMiddleware(Knex, {route: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const options = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(options); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with db driver app.use(wrapMainKnexAsMiddleware(Knex, {db_driver: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const tracing = require(\u0026#39;@opencensus/nodejs\u0026#39;); const {B3Format} = require(\u0026#39;@opencensus/propagation-b3\u0026#39;); const {ZipkinTraceExporter} = require(\u0026#39;@opencensus/exporter-zipkin\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const exporter = new ZipkinTraceExporter({ url: process.env.ZIPKIN_TRACE_URL || \u0026#39;localhost:9411/api/v2/spans\u0026#39;, serviceName: \u0026#39;trace-542\u0026#39; }); const b3 = new B3Format(); const traceOptions = { samplingRate: 1, // Always sample propagation: b3, exporter: exporter }; // start tracing tracing.start(traceOptions); const knexOptions = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with all attributes set app.use(wrapMainKnexAsMiddleware(Knex, { traceparent: true, tracestate: true, route: true, db_driver: true })); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); which after running by\n$ node app.js Application listening on 3000 Results On making a request to that server at http://localhost:3000/polls/1000, the PostgreSQL logs show:\nWith OpenCensus With Route With DB Driver With All Options Set 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*db_driver=\u0026#39;knex%3A0.0.1\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*db_driver=\u0026#39;knex%3A0.0.1\u0026#39;,route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;,traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ References Resource URL @google-cloud/sqlcommenter-knex on npm https://www.npmjs.com/package/@google-cloud/sqlcommenter-knex express.js https://expressjs.com/ " + "content": " Introduction Requirements Installation Manually Package manager Usage Plain knex wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Knex.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex.js.\nBesides plain knex.js wrapping, we also provide a wrapper for the following frameworks:\n Requirements Name Resource Knex.js https://knexjs.org/ Node.js https://nodejs.org/ Installation We can add integration into our applications in the following ways:\nManually Please read installing sqlcommenter-nodejs from source\nPackage manager Add to your package.json the dependency { \u0026#34;@google-cloud/sqlcommenter-knex\u0026#34;: \u0026#34;*\u0026#34; } and then run npm install to get the latest version or npm install @google-cloud/sqlcommenter-knex --save\nUsage Plain knex wrapper const {wrapMainKnex} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); wrapMainKnex(Knex); // Now you can create the knex client. const knex = Knex(options); Express middleware This wrapper/middleware can be used as is or better with express.js const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const Knex = require(\u0026#39;knex\u0026#39;); const app = require(\u0026#39;express\u0026#39;)(); // This is the important step where we set the middleware. app.use(wrapMainKnexAsMiddleware(Knex)); // Now you can create the knex client. const knex = Knex(options); \nFields In the database server logs, the comment\u0026rsquo;s fields are:\n comma separated key-value pairs e.g. route='%5Epolls/%24' values are SQL escaped i.e. key='value' URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. so should be URL-unquoted Field Format Description Example db_driver \u0026lt;database_driver\u0026gt;:\u0026lt;version\u0026gt; URL quoted name and version of the database driver db_driver='knex%3A0.16.5' route \u0026lt;the route used\u0026gt; URL quoted route used to match the express.js controller route='%5E%2Fpolls%2F traceparent \u0026lt;traceparent header\u0026gt; URL quoted W3C traceparent header traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01' tracestate \u0026lt;tracestate header\u0026gt; URL quoted W3C tracestate header tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE' Options When creating the middleware, one can optionally configure the injected comments by passing in the include and options objects:\nwrapMainKnexAsMiddleware(Knex, include={...}, options={...}); include config A map of values to be optionally included in the SQL comments.\n Field On by default db_driver \u0026#10060; route \u0026#10004; traceparent \u0026#10060; tracestate \u0026#10060; options config A configuration object specifying where to collect trace data from. Accepted fields are: TraceProvider: Should be OpenTelemetry, indicating which library to collect trace context from.\n Field Possible values TraceProvider OpenTelemetry Options examples trace attributes route db_driver all set wrapMainKnexAsMiddleware( Knex, include={ traceparent: true, tracestate: true }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); wrapMainKnexAsMiddleware(Knex, include={route: true}); wrapMainKnexAsMiddleware(Knex, include={db_driver: true}); // Manually set all the variables. wrapMainKnexAsMiddleware( Knex, include={ db_driver: true, route: true, traceparent: true, tracestate: true, }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); End to end examples Check out a full express + opentelemetry example here.\nSource code With OpenTelemetry With Route With DB Driver With All Options Set // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const express = require(\u0026#34;express\u0026#34;); const Knex = require(\u0026#34;knex\u0026#34;); const { wrapMainKnexAsMiddleware } = require(\u0026#34;@google-cloud/sqlcommenter-knex\u0026#34;); const knexOptions = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapMainKnexAsMiddleware( Knex, { traceparent: true, tracestate: true, // Optional db_driver: false, route: false, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const options = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(options); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with route app.use(wrapMainKnexAsMiddleware(Knex, {route: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js const Knex = require(\u0026#39;knex\u0026#39;); // Knex to be wrapped say v0.0.1 const {wrapMainKnexAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-knex\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const options = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(options); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // Use the knex+express middleware with db driver app.use(wrapMainKnexAsMiddleware(Knex, {db_driver: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const express = require(\u0026#34;express\u0026#34;); const Knex = require(\u0026#34;knex\u0026#34;); const { wrapMainKnexAsMiddleware } = require(\u0026#34;@google-cloud/sqlcommenter-knex\u0026#34;); const knexOptions = { client: \u0026#39;postgresql\u0026#39;, connection: { host: \u0026#39;127.0.0.1\u0026#39;, password: \u0026#39;$postgres$\u0026#39;, database: \u0026#39;quickstart_nodejs\u0026#39; } }; const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapMainKnexAsMiddleware( Knex, { traceparent: true, tracestate: true, // Optional db_driver: true, route: true, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { knex.raw(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); which after running by\n$ node app.js Application listening on 3000 Results On making a request to that server at http://localhost:3000/polls/1000, the PostgreSQL logs show:\nWith OpenTelemetry With Route With DB Driver With All Options Set 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*db_driver=\u0026#39;knex%3A0.0.1\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*db_driver=\u0026#39;knex%3A0.0.1\u0026#39;,route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;,traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ References Resource URL @google-cloud/sqlcommenter-knex on npm https://www.npmjs.com/package/@google-cloud/sqlcommenter-knex express.js https://expressjs.com/ " }, { "uri": "https://google.github.io/sqlcommenter/node/sequelize/", "title": "Sequelize.js", "tags": ["sequelize", "sequelize.js", "query-builder", "node", "node.js", "express", "express.js"], "description": "", - "content": " Requirements Installation Manually Package manager Usage Plain sequelize wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Sequelize.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Sequelize.js.\nBesides plain sequelize.js wrapping, we also provide a wrapper for the following frameworks:\n Requirements Sequelize.js Node.js Installation We can add integration into our applications in the following ways:\nManually Please read installing sqlcommenter-nodejs from source\nPackage manager Add to your package.json the dependency { \u0026#34;@google-cloud/sqlcommenter-sequelize\u0026#34;: \u0026#34;*\u0026#34; }\nand then run npm install to get the latest version or\nnpm install @google-cloud/sqlcommenter-sequelize --save Usage Plain sequelize wrapper const {wrapSequelize} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); // Create the sequelize client. const sequelize = new Sequelize(options); // Finally wrap the sequelize client. wrapSequelize(sequelize); Express middleware This wrapper/middleware can be used as is or better with express.js const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); const sequelize = new Sequelize(options); const app = require(\u0026#39;express\u0026#39;)(); // Use the sequelize+express middleware. app.use(wrapSequelizeAsMiddleware(sequelize)); \nFields In the database server logs, the comment\u0026rsquo;s fields are:\n comma separated key-value pairs e.g. route='%5E%2Fpolls%2F' values are SQL escaped i.e. key='value' URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. so should be URL-unquoted Field Format Description Example client_timezone \u0026lt;string\u0026gt; URL quoted name of the timezone used when converting a date from the database into a JavaScript date '+00:00' db_driver \u0026lt;sequelize\u0026gt; URL quoted name and version of the database driver db_driver='sequelize' route \u0026lt;the route used\u0026gt; URL quoted route used to match the express.js controller route='%5E%2Fpolls%2F traceparent \u0026lt;traceparent header\u0026gt; URL quoted W3C traceparent header traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01' tracestate \u0026lt;tracestate header\u0026gt; URL quoted W3C tracestate header tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE' Options When creating the middleware, one can optionally configure the injected comments by passing in the include and options objects:\nwrapMainSequelizeAsMiddleware(Sequelize, include={...}, options={...}); include config A map of values to be optionally included in the SQL comments.\n Field On by default client_timezone \u0026#10060; db_driver \u0026#10060; route \u0026#10004; traceparent \u0026#10060; tracestate \u0026#10060; options config A configuration object specifying where to collect trace data from. Accepted fields are: TraceProvider: Should be either OpenCensus or OpenTelemetry, indicating which library to collect trace context from.\n Field Possible values TraceProvider OpenCensus or OpenTelemetry Options examples trace attributes client_timezone route db_driver all set wrapMainSequelizeAsMiddleware( Sequelize, include={ traceparent: true, tracestate: true }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); wrapMainSequelizeAsMiddleware(Sequelize, include={client_timezone: true}); wrapMainSequelizeAsMiddleware(Sequelize, include={route: true}); wrapMainSequelizeAsMiddleware(Sequelize, include={db_driver: true}); // Manually set all the variables. wrapMainSequelizeAsMiddleware( Sequelize, include={ client_timezone: true, db_driver: true, route: true, traceparent: true, tracestate: true, }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); End to end examples Check out a full express + opentelemetry example here.\nSource code With OpenCensus With OpenTelemetry With Route With DB Driver and CLIENT TIMEZONE With All Options Set // In file app.js. const tracing = require(\u0026#39;@opencensus/nodejs\u0026#39;); const {B3Format} = require(\u0026#39;@opencensus/propagation-b3\u0026#39;); const {ZipkinTraceExporter} = require(\u0026#39;@opencensus/exporter-zipkin\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const exporter = new ZipkinTraceExporter({ url: process.env.ZIPKIN_TRACE_URL || \u0026#39;localhost://9411/api/v2/spans\u0026#39;, serviceName: \u0026#39;trace-542\u0026#39; }); const b3 = new B3Format(); const traceOptions = { samplingRate: 1, // Always sample propagation: b3, exporter: exporter }; // start tracing tracing.start(traceOptions); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with trace attributes app.use(wrapSequelizeAsMiddleware( sequelize, { traceparent: true, tracestate: true, route: false }, { TraceProvider: \u0026#34;OpenCensus\u0026#34; }, )); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const { Sequelize } = require(\u0026#34;sequelize\u0026#34;); const { wrapSequelizeAsMiddleware, } = require(\u0026#34;@google-cloud/sqlcommenter-sequelize\u0026#34;); const sequelize = new Sequelize(\u0026#34;postgres://user:pass@example.com:5432/dbname\u0026#34;); const express = require(\u0026#34;express\u0026#34;); const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapSequelizeAsMiddleware( sequelize, { client_timezone: true, db_driver: true, route: true, traceparent: true, tracestate: true, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#34;/\u0026#34;, (req, res) =\u0026gt; res.send(\u0026#34;Hello, sqlcommenter-nodejs!!\u0026#34;)); app.get(\u0026#34;^/polls/:param\u0026#34;, function (req, res) { sequelize .query(\u0026#34;SELECT * from polls_question\u0026#34;) .then(function (polls) { const blob = JSON.stringify(polls); res.send(blob); }) .catch(function (err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const Sequelize = require(\u0026#39;sequelize\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with route app.use(wrapSequelizeAsMiddleware(sequelize, {route: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js const Sequelize = require(\u0026#39;sequelize\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with db driver and timezone app.use(wrapSequelizeAsMiddleware(sequelize, { db_driver: true, client_timezone: true })); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const tracing = require(\u0026#39;@opencensus/nodejs\u0026#39;); const {B3Format} = require(\u0026#39;@opencensus/propagation-b3\u0026#39;); const {ZipkinTraceExporter} = require(\u0026#39;@opencensus/exporter-zipkin\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); const exporter = new ZipkinTraceExporter({ url: process.env.ZIPKIN_TRACE_URL || \u0026#39;localhost:9411/api/v2/spans\u0026#39;, serviceName: \u0026#39;trace-542\u0026#39; }); const b3 = new B3Format(); const traceOptions = { samplingRate: 1, // Always sample propagation: b3, exporter: exporter }; // start tracing tracing.start(traceOptions); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with all attributes set app.use(wrapSequelizeAsMiddleware( sequelize, { traceparent: true, tracestate: true, // Optional route: false, db_driver: false, client_timezone: false }, { TraceProvider: \u0026#34;OpenCensus\u0026#34;, }, )); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); which after running by\n$ node app.js Application listening on 3000 Results On making a request to that server at http://localhost:3000/polls/1000, the PostgreSQL logs show:\nWith OpenCensus With Route With DB Driver and CLIENT TIMEZONE With All Set 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*client_timezone:\u0026#39;%2B00%3A00\u0026#39;,db_driver=\u0026#39;sequelize%3A0.0.1\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*client_timezone:\u0026#39;%2B00%3A00\u0026#39;,db_driver=\u0026#39;sequelize%3A0.0.1\u0026#39;,route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;,traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ References Resource URL @google-cloud/sqlcommenter-sequelize on npm https://www.npmjs.com/package/@google-cloud/sqlcommenter-sequelize express.js https://expressjs.com/ " + "content": " Introduction Requirements Installation Manually Package manager Usage Plain sequelize wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Sequelize.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Sequelize.js.\nBesides plain sequelize.js wrapping, we also provide a wrapper for the following frameworks:\n Requirements Sequelize.js Node.js Installation We can add integration into our applications in the following ways:\nManually Please read installing sqlcommenter-nodejs from source\nPackage manager Add to your package.json the dependency { \u0026#34;@google-cloud/sqlcommenter-sequelize\u0026#34;: \u0026#34;*\u0026#34; }\nand then run npm install to get the latest version or\nnpm install @google-cloud/sqlcommenter-sequelize --save Usage Plain sequelize wrapper const {wrapSequelize} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); // Create the sequelize client. const sequelize = new Sequelize(options); // Finally wrap the sequelize client. wrapSequelize(sequelize); Express middleware This wrapper/middleware can be used as is or better with express.js const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const Sequelize = require(\u0026#39;sequelize\u0026#39;); const sequelize = new Sequelize(options); const app = require(\u0026#39;express\u0026#39;)(); // Use the sequelize+express middleware. app.use(wrapSequelizeAsMiddleware(sequelize)); \nFields In the database server logs, the comment\u0026rsquo;s fields are:\n comma separated key-value pairs e.g. route='%5E%2Fpolls%2F' values are SQL escaped i.e. key='value' URL-quoted except for the equals(=) sign e.g route='%5Epolls/%24'. so should be URL-unquoted Field Format Description Example client_timezone \u0026lt;string\u0026gt; URL quoted name of the timezone used when converting a date from the database into a JavaScript date '+00:00' db_driver \u0026lt;sequelize\u0026gt; URL quoted name and version of the database driver db_driver='sequelize' route \u0026lt;the route used\u0026gt; URL quoted route used to match the express.js controller route='%5E%2Fpolls%2F traceparent \u0026lt;traceparent header\u0026gt; URL quoted W3C traceparent header traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01' tracestate \u0026lt;tracestate header\u0026gt; URL quoted W3C tracestate header tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE' Options When creating the middleware, one can optionally configure the injected comments by passing in the include and options objects:\nwrapMainSequelizeAsMiddleware(Sequelize, include={...}, options={...}); include config A map of values to be optionally included in the SQL comments.\n Field On by default client_timezone \u0026#10060; db_driver \u0026#10060; route \u0026#10004; traceparent \u0026#10060; tracestate \u0026#10060; options config A configuration object specifying where to collect trace data from. Accepted fields are: TraceProvider: Should be OpenTelemetry, indicating which library to collect trace context from.\n Field Possible values TraceProvider OpenTelemetry Options examples trace attributes client_timezone route db_driver all set wrapMainSequelizeAsMiddleware( Sequelize, include={ traceparent: true, tracestate: true }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); wrapMainSequelizeAsMiddleware(Sequelize, include={client_timezone: true}); wrapMainSequelizeAsMiddleware(Sequelize, include={route: true}); wrapMainSequelizeAsMiddleware(Sequelize, include={db_driver: true}); // Manually set all the variables. wrapMainSequelizeAsMiddleware( Sequelize, include={ client_timezone: true, db_driver: true, route: true, traceparent: true, tracestate: true, }, options={ TraceProvider: \u0026#39;OpenTelemetry\u0026#39; } ); End to end examples Check out a full express + opentelemetry example here.\nSource code With OpenTelemetry With Route With DB Driver and CLIENT TIMEZONE With All Options Set // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const { Sequelize } = require(\u0026#34;sequelize\u0026#34;); const { wrapSequelizeAsMiddleware, } = require(\u0026#34;@google-cloud/sqlcommenter-sequelize\u0026#34;); const sequelize = new Sequelize(\u0026#34;postgres://user:pass@example.com:5432/dbname\u0026#34;); const express = require(\u0026#34;express\u0026#34;); const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapSequelizeAsMiddleware( sequelize, { client_timezone: false, db_driver: false, route: true, traceparent: true, tracestate: true, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#34;/\u0026#34;, (req, res) =\u0026gt; res.send(\u0026#34;Hello, sqlcommenter-nodejs!!\u0026#34;)); app.get(\u0026#34;^/polls/:param\u0026#34;, function (req, res) { sequelize .query(\u0026#34;SELECT * from polls_question\u0026#34;) .then(function (polls) { const blob = JSON.stringify(polls); res.send(blob); }) .catch(function (err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const Sequelize = require(\u0026#39;sequelize\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with route app.use(wrapSequelizeAsMiddleware(sequelize, {route: true})); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js const Sequelize = require(\u0026#39;sequelize\u0026#39;); const {wrapSequelizeAsMiddleware} = require(\u0026#39;@google-cloud/sqlcommenter-sequelize\u0026#39;); const express = require(\u0026#39;express\u0026#39;); // Using a connection URI const sequelize = new Sequelize(\u0026#39;postgres://user:pass@example.com:5432/dbname\u0026#39;); const app = express(); const port = process.env.APP_PORT || 3000; // Use the sequelize+express middleware with db driver and timezone app.use(wrapSequelizeAsMiddleware(sequelize, { db_driver: true, client_timezone: true })); app.get(\u0026#39;/\u0026#39;, (req, res) =\u0026gt; res.send(\u0026#39;Hello, sqlcommenter-nodejs!!\u0026#39;)); app.get(\u0026#39;^/polls/:param\u0026#39;, function(req, res) { sequelize.query(\u0026#39;SELECT * from polls_question\u0026#39;).then(function(polls) { const blob = JSON.stringify(polls); res.send(blob); }).catch(function(err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); // In file app.js. const { NodeTracerProvider } = require(\u0026#34;@opentelemetry/node\u0026#34;); const { BatchSpanProcessor } = require(\u0026#34;@opentelemetry/tracing\u0026#34;); const { TraceExporter, } = require(\u0026#34;@google-cloud/opentelemetry-cloud-trace-exporter\u0026#34;); const tracerProvider = new NodeTracerProvider(); // Export to Google Cloud Trace tracerProvider.addSpanProcessor( new BatchSpanProcessor(new TraceExporter({ logger }), { bufferSize: 500, bufferTimeout: 5 * 1000, }) ); tracerProvider.register(); // OpenTelemetry initialization should happen before importing any libraries // that it instruments const { Sequelize } = require(\u0026#34;sequelize\u0026#34;); const { wrapSequelizeAsMiddleware, } = require(\u0026#34;@google-cloud/sqlcommenter-sequelize\u0026#34;); const sequelize = new Sequelize(\u0026#34;postgres://user:pass@example.com:5432/dbname\u0026#34;); const express = require(\u0026#34;express\u0026#34;); const app = express(); const port = process.env.APP_PORT || 3000; // SQLCommenter express middleware injects the route into the traces app.use( wrapSequelizeAsMiddleware( sequelize, { client_timezone: true, db_driver: true, route: true, traceparent: true, tracestate: true, }, { TraceProvider: \u0026#34;OpenTelemetry\u0026#34; } ) ); app.get(\u0026#34;/\u0026#34;, (req, res) =\u0026gt; res.send(\u0026#34;Hello, sqlcommenter-nodejs!!\u0026#34;)); app.get(\u0026#34;^/polls/:param\u0026#34;, function (req, res) { sequelize .query(\u0026#34;SELECT * from polls_question\u0026#34;) .then(function (polls) { const blob = JSON.stringify(polls); res.send(blob); }) .catch(function (err) { console.log(err); res.send(500); }); }); app.listen(port, () =\u0026gt; console.log(`Application listening on ${port}`)); which after running by\n$ node app.js Application listening on 3000 Results On making a request to that server at http://localhost:3000/polls/1000, the PostgreSQL logs show:\nWith OpenTelemetry With Route With DB Driver and CLIENT TIMEZONE With All Set 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*client_timezone:\u0026#39;%2B00%3A00\u0026#39;,db_driver=\u0026#39;sequelize%3A0.0.1\u0026#39;*/ 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question /*client_timezone:\u0026#39;%2B00%3A00\u0026#39;,db_driver=\u0026#39;sequelize%3A0.0.1\u0026#39;,route=\u0026#39;%5E%2Fpolls%2F%1000\u0026#39;,traceparent=\u0026#39;00-11000000000000ff-020000ee-01\u0026#39;,tracestate=\u0026#39;brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7\u0026#39;*/ References Resource URL @google-cloud/sqlcommenter-sequelize on npm https://www.npmjs.com/package/@google-cloud/sqlcommenter-sequelize express.js https://expressjs.com/ " }, { "uri": "https://google.github.io/sqlcommenter/spec/", diff --git a/node/express/index.html b/node/express/index.html index 22107f28..d8236b14 100644 --- a/node/express/index.html +++ b/node/express/index.html @@ -317,7 +317,7 @@

Express.js

  • Introduction
  • References
  • -

    Introduction

    +

    Introduction

    We provide express.js application-level middleware with the following ORMs/Query-Builders:

    diff --git a/node/knex/index.html b/node/knex/index.html index 8861cedd..f2b8dd86 100644 --- a/node/knex/index.html +++ b/node/knex/index.html @@ -339,15 +339,15 @@

    Knex.js

    -
  • End to end examples +
  • End to end examples
  • -
  • References
  • -

    Introduction

    +

    Introduction

    This package is in the form of Knex.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex.js.

    Besides plain knex.js wrapping, we also provide a wrapper for the following frameworks:

    @@ -491,7 +491,7 @@

    Options

    options config

    A configuration object specifying where to collect trace data from. Accepted -fields are: TraceProvider: Should be either OpenCensus or OpenTelemetry, +fields are: TraceProvider: Should be OpenTelemetry, indicating which library to collect trace context from.

    @@ -503,7 +503,7 @@
    options config
    - +
    TraceProviderOpenCensus or OpenTelemetryOpenTelemetry
    @@ -570,23 +570,19 @@

    Source code

    @@ -594,62 +590,6 @@

    Source code

    -
    // In file app.js.
    -const tracing = require('@opencensus/nodejs');
    -const {B3Format} = require('@opencensus/propagation-b3');
    -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin');
    -const Knex = require('knex'); // Knex to be wrapped say v0.0.1
    -const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
    -const express = require('express');
    -
    -const exporter = new ZipkinTraceExporter({
    -    url: process.env.ZIPKIN_TRACE_URL || 'localhost://9411/api/v2/spans',
    -    serviceName: 'trace-542'
    -});
    -
    -const b3 = new B3Format();
    -const traceOptions = {
    -    samplingRate: 1, // Always sample
    -    propagation: b3,
    -    exporter: exporter
    -};
    -
    -// start tracing
    -tracing.start(traceOptions);
    -
    -const knexOptions = {
    -    client: 'postgresql',
    -    connection: {
    -        host: '127.0.0.1',
    -        password: '$postgres$',
    -        database: 'quickstart_nodejs'
    -    }
    -};
    -const knex = Knex(knexOptions); // knex instance
    -
    -const app = express();
    -const port = process.env.APP_PORT || 3000;
    -
    -// Use the knex+express middleware with trace attributes
    -app.use(wrapMainKnexAsMiddleware(Knex, {
    -    traceparent: true,
    -    tracestate: true,
    -    route: false
    -}));
    -
    -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!'));
    -app.get('^/polls/:param', function(req, res) {
    -    knex.raw('SELECT * from polls_question').then(function(polls) {
    -        const blob = JSON.stringify(polls);
    -        res.send(blob);
    -    }).catch(function(err) {
    -        console.log(err);
    -        res.send(500);
    -    });
    -});
    -app.listen(port, () => console.log(`Application listening on ${port}`));
    -
    -
    // In file app.js.
     const { NodeTracerProvider } = require("@opentelemetry/node");
     const { BatchSpanProcessor } = require("@opentelemetry/tracing");
    @@ -785,27 +725,27 @@ 

    Source code

    // In file app.js.
    -const tracing = require('@opencensus/nodejs');
    -const {B3Format} = require('@opencensus/propagation-b3');
    -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin');
    -const Knex = require('knex'); // Knex to be wrapped say v0.0.1
    -const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex');
    -const express = require('express');
    -
    -const exporter = new ZipkinTraceExporter({
    -    url: process.env.ZIPKIN_TRACE_URL || 'localhost:9411/api/v2/spans',
    -    serviceName: 'trace-542'
    -});
    +const { NodeTracerProvider } = require("@opentelemetry/node");
    +const { BatchSpanProcessor } = require("@opentelemetry/tracing");
    +const {
    +  TraceExporter,
    +} = require("@google-cloud/opentelemetry-cloud-trace-exporter");
     
    -const b3 = new B3Format();
    -const traceOptions = {
    -    samplingRate: 1, // Always sample
    -    propagation: b3,
    -    exporter: exporter
    -};
    +const tracerProvider = new NodeTracerProvider();
    +// Export to Google Cloud Trace
    +tracerProvider.addSpanProcessor(
    +  new BatchSpanProcessor(new TraceExporter({ logger }), {
    +    bufferSize: 500,
    +    bufferTimeout: 5 * 1000,
    +  })
    +);
    +tracerProvider.register();
     
    -// start tracing
    -tracing.start(traceOptions);
    +// OpenTelemetry initialization should happen before importing any libraries
    +// that it instruments
    +const express = require("express");
    +const Knex = require("knex");
    +const { wrapMainKnexAsMiddleware } = require("@google-cloud/sqlcommenter-knex");
     
     const knexOptions = {
         client: 'postgresql',
    @@ -820,13 +760,21 @@ 

    Source code

    const app = express(); const port = process.env.APP_PORT || 3000; -// Use the knex+express middleware with all attributes set -app.use(wrapMainKnexAsMiddleware(Knex, { - traceparent: true, - tracestate: true, - route: true, - db_driver: true -})); +// SQLCommenter express middleware injects the route into the traces +app.use( + wrapMainKnexAsMiddleware( + Knex, + { + traceparent: true, + tracestate: true, + + // Optional + db_driver: true, + route: true, + }, + { TraceProvider: "OpenTelemetry" } + ) +); app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!')); app.get('^/polls/:param', function(req, res) { @@ -854,7 +802,7 @@

    Source code

    • - With OpenCensus + With OpenTelemetry
    • diff --git a/node/sequelize/index.html b/node/sequelize/index.html index 74bb350e..b898905f 100644 --- a/node/sequelize/index.html +++ b/node/sequelize/index.html @@ -314,6 +314,7 @@

      Sequelize.js

      -

      Introduction

      +

      Introduction

      This package is in the form of Sequelize.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Sequelize.js.

      Besides plain sequelize.js wrapping, we also provide a wrapper for the following frameworks:

      @@ -487,7 +488,7 @@

      Options

      options config

      A configuration object specifying where to collect trace data from. Accepted -fields are: TraceProvider: Should be either OpenCensus or OpenTelemetry, +fields are: TraceProvider: Should be OpenTelemetry, indicating which library to collect trace context from.

      @@ -499,7 +500,7 @@
      options config
      - +
      TraceProviderOpenCensus or OpenTelemetryOpenTelemetry
      @@ -574,23 +575,19 @@

      Source code

      @@ -598,55 +595,6 @@

      Source code

      -
      // In file app.js.
      -const tracing = require('@opencensus/nodejs');
      -const {B3Format} = require('@opencensus/propagation-b3');
      -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin');
      -const {wrapSequelizeAsMiddleware} = require('@google-cloud/sqlcommenter-sequelize');
      -const Sequelize = require('sequelize');
      -const express = require('express');
      -
      -const exporter = new ZipkinTraceExporter({
      -    url: process.env.ZIPKIN_TRACE_URL || 'localhost://9411/api/v2/spans',
      -    serviceName: 'trace-542'
      -});
      -
      -const b3 = new B3Format();
      -const traceOptions = {
      -    samplingRate: 1, // Always sample
      -    propagation: b3,
      -    exporter: exporter
      -};
      -
      -// start tracing
      -tracing.start(traceOptions);
      -
      -// Using a connection URI
      -const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname');
      -
      -const app = express();
      -const port = process.env.APP_PORT || 3000;
      -
      -// Use the sequelize+express middleware with trace attributes 
      -app.use(wrapSequelizeAsMiddleware(
      -    sequelize,
      -    { traceparent: true, tracestate: true, route: false },
      -    { TraceProvider: "OpenCensus" },
      -));
      -
      -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!'));
      -app.get('^/polls/:param', function(req, res) {
      -    sequelize.query('SELECT * from polls_question').then(function(polls) {
      -        const blob = JSON.stringify(polls);
      -        res.send(blob);
      -    }).catch(function(err) {
      -        console.log(err);
      -        res.send(500);
      -    });
      -});
      -app.listen(port, () => console.log(`Application listening on ${port}`));
      -
      -
      // In file app.js.
       const { NodeTracerProvider } = require("@opentelemetry/node");
       const { BatchSpanProcessor } = require("@opentelemetry/tracing");
      @@ -682,8 +630,8 @@ 

      Source code

      wrapSequelizeAsMiddleware( sequelize, { - client_timezone: true, - db_driver: true, + client_timezone: false, + db_driver: false, route: true, traceparent: true, tracestate: true, @@ -767,59 +715,61 @@

      Source code

      // In file app.js.
      -const tracing = require('@opencensus/nodejs');
      -const {B3Format} = require('@opencensus/propagation-b3');
      -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin');
      -const Sequelize = require('sequelize');
      -const {wrapSequelizeAsMiddleware} = require('@google-cloud/sqlcommenter-sequelize');
      -const express = require('express');
      -
      -const exporter = new ZipkinTraceExporter({
      -    url: process.env.ZIPKIN_TRACE_URL || 'localhost:9411/api/v2/spans',
      -    serviceName: 'trace-542'
      -});
      +const { NodeTracerProvider } = require("@opentelemetry/node");
      +const { BatchSpanProcessor } = require("@opentelemetry/tracing");
      +const {
      +  TraceExporter,
      +} = require("@google-cloud/opentelemetry-cloud-trace-exporter");
       
      -const b3 = new B3Format();
      -const traceOptions = {
      -    samplingRate: 1, // Always sample
      -    propagation: b3,
      -    exporter: exporter
      -};
      +const tracerProvider = new NodeTracerProvider();
      +// Export to Google Cloud Trace
      +tracerProvider.addSpanProcessor(
      +  new BatchSpanProcessor(new TraceExporter({ logger }), {
      +    bufferSize: 500,
      +    bufferTimeout: 5 * 1000,
      +  })
      +);
      +tracerProvider.register();
       
      -// start tracing
      -tracing.start(traceOptions);
      +// OpenTelemetry initialization should happen before importing any libraries
      +// that it instruments
      +const { Sequelize } = require("sequelize");
      +const {
      +  wrapSequelizeAsMiddleware,
      +} = require("@google-cloud/sqlcommenter-sequelize");
       
      -// Using a connection URI
      -const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname');
      +const sequelize = new Sequelize("postgres://user:pass@example.com:5432/dbname");
       
      +const express = require("express");
       const app = express();
       const port = process.env.APP_PORT || 3000;
       
      -// Use the sequelize+express middleware with all attributes set
      -app.use(wrapSequelizeAsMiddleware(
      +// SQLCommenter express middleware injects the route into the traces
      +app.use(
      +  wrapSequelizeAsMiddleware(
           sequelize,
           {
      -        traceparent: true,
      -        tracestate: true,
      -
      -        // Optional
      -        route: false,
      -        db_driver: false,
      -        client_timezone: false
      -    },
      -    {
      -        TraceProvider: "OpenCensus",
      +      client_timezone: true,
      +      db_driver: true,
      +      route: true,
      +      traceparent: true,
      +      tracestate: true,
           },
      -));
      +    { TraceProvider: "OpenTelemetry" }
      +  )
      +);
       
      -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!'));
      -app.get('^/polls/:param', function(req, res) {
      -    sequelize.query('SELECT * from polls_question').then(function(polls) {
      -        const blob = JSON.stringify(polls);
      -        res.send(blob);
      -    }).catch(function(err) {
      -        console.log(err);
      -        res.send(500);
      +app.get("/", (req, res) => res.send("Hello, sqlcommenter-nodejs!!"));
      +app.get("^/polls/:param", function (req, res) {
      +  sequelize
      +    .query("SELECT * from polls_question")
      +    .then(function (polls) {
      +      const blob = JSON.stringify(polls);
      +      res.send(blob);
      +    })
      +    .catch(function (err) {
      +      console.log(err);
      +      res.send(500);
           });
       });
       app.listen(port, () => console.log(`Application listening on ${port}`));
      @@ -838,7 +788,7 @@ 

      Source code

      • - With OpenCensus + With OpenTelemetry
      • diff --git a/src/content/node/express/_index.md b/src/content/node/express/_index.md index 13f598a8..8ff50fa4 100644 --- a/src/content/node/express/_index.md +++ b/src/content/node/express/_index.md @@ -11,7 +11,7 @@ tags: ["express", "express.js", "middleware", "node", "node.js"] - [Introduction](#introduction) - [References](#references) -#### Introduction +### Introduction We provide [express.js application-level middleware](https://expressjs.com/en/guide/using-middleware.html#middleware.application) with the following ORMs/Query-Builders: @@ -20,7 +20,7 @@ We provide [express.js application-level middleware](https://expressjs.com/en/gu ### References -Resource|URL ----|--- -express.js|https://expressjs.com/ -express.js middleware|https://expressjs.com/en/guide/using-middleware.html +| Resource | URL | +| --------------------- | ---------------------------------------------------- | +| express.js | https://expressjs.com/ | +| express.js middleware | https://expressjs.com/en/guide/using-middleware.html | diff --git a/src/content/node/knex/_index.md b/src/content/node/knex/_index.md index ae0379b1..15f918f3 100644 --- a/src/content/node/knex/_index.md +++ b/src/content/node/knex/_index.md @@ -11,22 +11,22 @@ tags: ["knex", "knex.js", "query-builder", "node", "node.js", "express", "expres - [Introduction](#introduction) - [Requirements](#requirements) - [Installation](#installation) - - [Manually](#manually) - - [Package manager](#package-manager) + - [Manually](#manually) + - [Package manager](#package-manager) - [Usage](#usage) - - [Plain knex wrapper](#plain-knex-wrapper) - - [Express middleware](#express-middleware) + - [Plain knex wrapper](#plain-knex-wrapper) + - [Express middleware](#express-middleware) - [Fields](#fields) - - [Options](#options) - - [`include` config](#include-config) - - [`options` config](#options-config) - - [Options examples](#options-examples) -- [End to end examples](#end-to-examples) - - [Source code](#source-code) - - [Results](#results) -- [References](#references) + - [Options](#options) + - [`include` config](#include-config) + - [`options` config](#options-config) + - [Options examples](#options-examples) +- [End to end examples](#end-to-end-examples) + - [Source code](#source-code) + - [Results](#results) + - [References](#references) -#### Introduction +### Introduction This package is in the form of `Knex.Client.prototype.query` wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex.js. @@ -37,10 +37,10 @@ Besides plain knex.js wrapping, we also provide a wrapper for the following fram ### Requirements -Name|Resource ----|--- -Knex.js|https://knexjs.org/ -Node.js|https://nodejs.org/ +| Name | Resource | +| ------- | ------------------- | +| Knex.js | https://knexjs.org/ | +| Node.js | https://nodejs.org/ | ### Installation @@ -95,12 +95,12 @@ In the database server logs, the comment's fields are: * values are SQL escaped i.e. `key='value'` * URL-quoted except for the equals(`=`) sign e.g `route='%5Epolls/%24'`. so should be URL-unquoted -| Field | Format | Description | Example | -|-------------------|-------------------------------|------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| -| `db_driver` | `:` | URL quoted name and version of the database driver | `db_driver='knex%3A0.16.5'` | -| `route` | `` | URL quoted route used to match the express.js controller | `route='%5E%2Fpolls%2F` | -| `traceparent` | `` | URL quoted [W3C `traceparent` header](https://www.w3.org/TR/trace-context/#traceparent-header) | `traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01'` | -| `tracestate` | `` | URL quoted [W3C `tracestate` header](https://www.w3.org/TR/trace-context/#tracestate-header) | `tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE'` | +| Field | Format | Description | Example | +| ------------- | ----------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| `db_driver` | `:` | URL quoted name and version of the database driver | `db_driver='knex%3A0.16.5'` | +| `route` | `` | URL quoted route used to match the express.js controller | `route='%5E%2Fpolls%2F` | +| `traceparent` | `` | URL quoted [W3C `traceparent` header](https://www.w3.org/TR/trace-context/#traceparent-header) | `traceparent='00-3e2914ebce6af09508dd1ff1128493a8-81d09ab4d8cde7cf-01'` | +| `tracestate` | `` | URL quoted [W3C `tracestate` header](https://www.w3.org/TR/trace-context/#tracestate-header) | `tracestate='rojo%253D00f067aa0ba902b7%2Ccongo%253Dt61rcWkgMzE'` | #### Options @@ -115,7 +115,7 @@ wrapMainKnexAsMiddleware(Knex, include={...}, options={...}); A map of values to be optionally included in the SQL comments. | Field | On by default | -|-------------|---------------| +| ----------- | ------------- | | db_driver | {{}} | | route | {{}} | | traceparent | {{}} | @@ -123,12 +123,12 @@ A map of values to be optionally included in the SQL comments. ##### `options` config A configuration object specifying where to collect trace data from. Accepted -fields are: TraceProvider: Should be either `OpenCensus` or `OpenTelemetry`, +fields are: TraceProvider: Should be `OpenTelemetry`, indicating which library to collect trace context from. -| Field | Possible values | -|---------------|---------------------------------| -| TraceProvider | `OpenCensus` or `OpenTelemetry` | +| Field | Possible values | +| ------------- | --------------- | +| TraceProvider | `OpenTelemetry` | ##### Options examples @@ -173,64 +173,7 @@ Check out a full express + opentelemetry example #### Source code -{{}} - -{{}} -// In file app.js. -const tracing = require('@opencensus/nodejs'); -const {B3Format} = require('@opencensus/propagation-b3'); -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin'); -const Knex = require('knex'); // Knex to be wrapped say v0.0.1 -const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex'); -const express = require('express'); - -const exporter = new ZipkinTraceExporter({ - url: process.env.ZIPKIN_TRACE_URL || 'localhost://9411/api/v2/spans', - serviceName: 'trace-542' -}); - -const b3 = new B3Format(); -const traceOptions = { - samplingRate: 1, // Always sample - propagation: b3, - exporter: exporter -}; - -// start tracing -tracing.start(traceOptions); - -const knexOptions = { - client: 'postgresql', - connection: { - host: '127.0.0.1', - password: '$postgres$', - database: 'quickstart_nodejs' - } -}; -const knex = Knex(knexOptions); // knex instance - -const app = express(); -const port = process.env.APP_PORT || 3000; - -// Use the knex+express middleware with trace attributes -app.use(wrapMainKnexAsMiddleware(Knex, { - traceparent: true, - tracestate: true, - route: false -})); - -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!')); -app.get('^/polls/:param', function(req, res) { - knex.raw('SELECT * from polls_question').then(function(polls) { - const blob = JSON.stringify(polls); - res.send(blob); - }).catch(function(err) { - console.log(err); - res.send(500); - }); -}); -app.listen(port, () => console.log(`Application listening on ${port}`)); -{{}} +{{}} {{}} // In file app.js. @@ -371,27 +314,27 @@ app.listen(port, () => console.log(`Application listening on ${port}`)); {{}} // In file app.js. -const tracing = require('@opencensus/nodejs'); -const {B3Format} = require('@opencensus/propagation-b3'); -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin'); -const Knex = require('knex'); // Knex to be wrapped say v0.0.1 -const {wrapMainKnexAsMiddleware} = require('@google-cloud/sqlcommenter-knex'); -const express = require('express'); - -const exporter = new ZipkinTraceExporter({ - url: process.env.ZIPKIN_TRACE_URL || 'localhost:9411/api/v2/spans', - serviceName: 'trace-542' -}); +const { NodeTracerProvider } = require("@opentelemetry/node"); +const { BatchSpanProcessor } = require("@opentelemetry/tracing"); +const { + TraceExporter, +} = require("@google-cloud/opentelemetry-cloud-trace-exporter"); -const b3 = new B3Format(); -const traceOptions = { - samplingRate: 1, // Always sample - propagation: b3, - exporter: exporter -}; +const tracerProvider = new NodeTracerProvider(); +// Export to Google Cloud Trace +tracerProvider.addSpanProcessor( + new BatchSpanProcessor(new TraceExporter({ logger }), { + bufferSize: 500, + bufferTimeout: 5 * 1000, + }) +); +tracerProvider.register(); -// start tracing -tracing.start(traceOptions); +// OpenTelemetry initialization should happen before importing any libraries +// that it instruments +const express = require("express"); +const Knex = require("knex"); +const { wrapMainKnexAsMiddleware } = require("@google-cloud/sqlcommenter-knex"); const knexOptions = { client: 'postgresql', @@ -406,13 +349,21 @@ const knex = Knex(knexOptions); // knex instance const app = express(); const port = process.env.APP_PORT || 3000; -// Use the knex+express middleware with all attributes set -app.use(wrapMainKnexAsMiddleware(Knex, { - traceparent: true, - tracestate: true, - route: true, - db_driver: true -})); +// SQLCommenter express middleware injects the route into the traces +app.use( + wrapMainKnexAsMiddleware( + Knex, + { + traceparent: true, + tracestate: true, + + // Optional + db_driver: true, + route: true, + }, + { TraceProvider: "OpenTelemetry" } + ) +); app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!')); app.get('^/polls/:param', function(req, res) { @@ -439,7 +390,7 @@ Application listening on 3000 On making a request to that server at `http://localhost:3000/polls/1000`, the PostgreSQL logs show: -{{}} +{{}} {{}} 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question @@ -466,6 +417,6 @@ On making a request to that server at `http://localhost:3000/polls/1000`, the Po #### References | Resource | URL | -|----------------------------------------|---------------------------------------------------------------| +| -------------------------------------- | ------------------------------------------------------------- | | @google-cloud/sqlcommenter-knex on npm | https://www.npmjs.com/package/@google-cloud/sqlcommenter-knex | | express.js | https://expressjs.com/ | diff --git a/src/content/node/sequelize/_index.md b/src/content/node/sequelize/_index.md index 2c10b214..5c40607c 100644 --- a/src/content/node/sequelize/_index.md +++ b/src/content/node/sequelize/_index.md @@ -8,6 +8,7 @@ tags: ["sequelize", "sequelize.js", "query-builder", "node", "node.js", "express ![](/images/sequelize-logo.png) +- [Introduction](#introduction) - [Requirements](#requirements) - [Installation](#installation) - [Manually](#manually) @@ -25,7 +26,7 @@ tags: ["sequelize", "sequelize.js", "query-builder", "node", "node.js", "express - [Results](#results) - [References](#references) -#### Introduction +### Introduction This package is in the form of `Sequelize.Client.prototype.query` wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Sequelize.js. @@ -95,7 +96,7 @@ In the database server logs, the comment's fields are: * URL-quoted except for the equals(`=`) sign e.g `route='%5Epolls/%24'`. so should be URL-unquoted | Field | Format | Description | Example | -|-------------------|------------------------|------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------| +| ----------------- | ---------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | `client_timezone` | `` | URL quoted name of the timezone used when converting a date from the database into a JavaScript date | `'+00:00'` | | `db_driver` | `` | URL quoted name and version of the database driver | `db_driver='sequelize'` | | `route` | `` | URL quoted route used to match the express.js controller | `route='%5E%2Fpolls%2F` | @@ -114,7 +115,7 @@ wrapMainSequelizeAsMiddleware(Sequelize, include={...}, options={...}); A map of values to be optionally included in the SQL comments. | Field | On by default | -|-----------------|---------------| +| --------------- | ------------- | | client_timezone | {{}} | | db_driver | {{}} | | route | {{}} | @@ -123,12 +124,12 @@ A map of values to be optionally included in the SQL comments. ##### `options` config A configuration object specifying where to collect trace data from. Accepted -fields are: TraceProvider: Should be either `OpenCensus` or `OpenTelemetry`, +fields are: TraceProvider: Should be `OpenTelemetry`, indicating which library to collect trace context from. -| Field | Possible values | -|---------------|---------------------------------| -| TraceProvider | `OpenCensus` or `OpenTelemetry` | +| Field | Possible values | +| ------------- | --------------- | +| TraceProvider | `OpenTelemetry` | ##### Options examples @@ -178,57 +179,7 @@ Check out a full express + opentelemetry example #### Source code -{{}} - -{{}} -// In file app.js. -const tracing = require('@opencensus/nodejs'); -const {B3Format} = require('@opencensus/propagation-b3'); -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin'); -const {wrapSequelizeAsMiddleware} = require('@google-cloud/sqlcommenter-sequelize'); -const Sequelize = require('sequelize'); -const express = require('express'); - -const exporter = new ZipkinTraceExporter({ - url: process.env.ZIPKIN_TRACE_URL || 'localhost://9411/api/v2/spans', - serviceName: 'trace-542' -}); - -const b3 = new B3Format(); -const traceOptions = { - samplingRate: 1, // Always sample - propagation: b3, - exporter: exporter -}; - -// start tracing -tracing.start(traceOptions); - -// Using a connection URI -const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname'); - -const app = express(); -const port = process.env.APP_PORT || 3000; - -// Use the sequelize+express middleware with trace attributes -app.use(wrapSequelizeAsMiddleware( - sequelize, - { traceparent: true, tracestate: true, route: false }, - { TraceProvider: "OpenCensus" }, -)); - -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!')); -app.get('^/polls/:param', function(req, res) { - sequelize.query('SELECT * from polls_question').then(function(polls) { - const blob = JSON.stringify(polls); - res.send(blob); - }).catch(function(err) { - console.log(err); - res.send(500); - }); -}); -app.listen(port, () => console.log(`Application listening on ${port}`)); -{{}} +{{}} {{}} // In file app.js. @@ -266,8 +217,8 @@ app.use( wrapSequelizeAsMiddleware( sequelize, { - client_timezone: true, - db_driver: true, + client_timezone: false, + db_driver: false, route: true, traceparent: true, tracestate: true, @@ -354,59 +305,61 @@ app.listen(port, () => console.log(`Application listening on ${port}`)); {{}} // In file app.js. -const tracing = require('@opencensus/nodejs'); -const {B3Format} = require('@opencensus/propagation-b3'); -const {ZipkinTraceExporter} = require('@opencensus/exporter-zipkin'); -const Sequelize = require('sequelize'); -const {wrapSequelizeAsMiddleware} = require('@google-cloud/sqlcommenter-sequelize'); -const express = require('express'); - -const exporter = new ZipkinTraceExporter({ - url: process.env.ZIPKIN_TRACE_URL || 'localhost:9411/api/v2/spans', - serviceName: 'trace-542' -}); +const { NodeTracerProvider } = require("@opentelemetry/node"); +const { BatchSpanProcessor } = require("@opentelemetry/tracing"); +const { + TraceExporter, +} = require("@google-cloud/opentelemetry-cloud-trace-exporter"); -const b3 = new B3Format(); -const traceOptions = { - samplingRate: 1, // Always sample - propagation: b3, - exporter: exporter -}; +const tracerProvider = new NodeTracerProvider(); +// Export to Google Cloud Trace +tracerProvider.addSpanProcessor( + new BatchSpanProcessor(new TraceExporter({ logger }), { + bufferSize: 500, + bufferTimeout: 5 * 1000, + }) +); +tracerProvider.register(); -// start tracing -tracing.start(traceOptions); +// OpenTelemetry initialization should happen before importing any libraries +// that it instruments +const { Sequelize } = require("sequelize"); +const { + wrapSequelizeAsMiddleware, +} = require("@google-cloud/sqlcommenter-sequelize"); -// Using a connection URI -const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname'); +const sequelize = new Sequelize("postgres://user:pass@example.com:5432/dbname"); +const express = require("express"); const app = express(); const port = process.env.APP_PORT || 3000; -// Use the sequelize+express middleware with all attributes set -app.use(wrapSequelizeAsMiddleware( +// SQLCommenter express middleware injects the route into the traces +app.use( + wrapSequelizeAsMiddleware( sequelize, { - traceparent: true, - tracestate: true, - - // Optional - route: false, - db_driver: false, - client_timezone: false - }, - { - TraceProvider: "OpenCensus", + client_timezone: true, + db_driver: true, + route: true, + traceparent: true, + tracestate: true, }, -)); + { TraceProvider: "OpenTelemetry" } + ) +); -app.get('/', (req, res) => res.send('Hello, sqlcommenter-nodejs!!')); -app.get('^/polls/:param', function(req, res) { - sequelize.query('SELECT * from polls_question').then(function(polls) { - const blob = JSON.stringify(polls); - res.send(blob); - }).catch(function(err) { - console.log(err); - res.send(500); +app.get("/", (req, res) => res.send("Hello, sqlcommenter-nodejs!!")); +app.get("^/polls/:param", function (req, res) { + sequelize + .query("SELECT * from polls_question") + .then(function (polls) { + const blob = JSON.stringify(polls); + res.send(blob); + }) + .catch(function (err) { + console.log(err); + res.send(500); }); }); app.listen(port, () => console.log(`Application listening on ${port}`)); @@ -424,7 +377,7 @@ Application listening on 3000 On making a request to that server at `http://localhost:3000/polls/1000`, the PostgreSQL logs show: -{{}} +{{}} {{}} 2019-06-03 14:32:10.842 PDT [32004] LOG: statement: SELECT * from polls_question @@ -452,6 +405,6 @@ On making a request to that server at `http://localhost:3000/polls/1000`, the Po #### References | Resource | URL | -|---------------------------------------------|--------------------------------------------------------------------| +| ------------------------------------------- | ------------------------------------------------------------------ | | @google-cloud/sqlcommenter-sequelize on npm | https://www.npmjs.com/package/@google-cloud/sqlcommenter-sequelize | | express.js | https://expressjs.com/ | diff --git a/tags/express.js/index.html b/tags/express.js/index.html index 6f22f36c..0683912d 100644 --- a/tags/express.js/index.html +++ b/tags/express.js/index.html @@ -328,7 +328,7 @@

        express.js

        Knex.js

        -

        Introduction Requirements Installation Manually Package manager Usage Plain knex wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Knex.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex. »

        +

        Introduction Requirements Installation Manually Package manager Usage Plain knex wrapper Express middleware Fields Options include config options config Options examples End to end examples Source code Results References Introduction This package is in the form of Knex.Client.prototype.query wrapper whose purpose is to augment a SQL statement right before execution, with information about the controller and user code to help correlate them with SQL statements emitted by Knex. »