Giter Club home page Giter Club logo

node-diagnostic-channel's Introduction

diagnostic-channel

What?

diagnostic-channel provides a shared channel for handling instrumentation and diagnostic messages in Node.js apps. Instrumentation patchers and module authors can publish messages to this channel by calling channel.publish(...), and APM providers and other tools can subscribe to those messages by calling channel.subscribe(...). Subscribers can transform the original generic message as needed in their handlers and relay the message on to storage and monitoring systems.

diagnostic-channel-publishers provides a set of patches for common Node.js modules to publish instrumentation data to the diagnostic-channel channel.

Why?

By providing a shared message bus, diagnostic-channel will allow re-use of the same instrumentation patches by many tools and APM providers. We believe that sharing a common bus and patches will enable the Node.js community to collaborate more with module authors and tool providers to improve and increase collected data. Ultimately this will help us all achieve our true goal of serving more helpful insights to Node.js developers.

Beyond console.log and its weaknesses, module authors and even core contributors have had few dependable ways to share traces, metrics, and other data collected by their systems and modules. The Node.js Diagnostics WG has several efforts in flight to address this, including trace_events support, Inspector, and async_hooks. This diagnostic-channel project is another part of these efforts.

How to Use

If you're a module author you can produce output directly from your own modules for the shared channel. If you're patching someone else's module you'll need to implement a publisher/patcher to patch in your instrumentation.

In either case, to get started:

  1. Add diagnostic-channel to your module: npm install --save diagnostic-channel.
  2. Import it within your module: const channel = require('diagnostic-channel').channel.
  3. Use APIs such as channel.subscribe(...) and channel.publish(...) to publish or handle diagnostic messages.

To use the set of publisher patches from this repo: require('diagnostic-channel-publishers').enable().

If you're creating a publisher/patcher for another module, start from one of the included publishers in src/diagnostic-channel-publishers/src and see Contributing below

License

MIT. See LICENSE.

Contributing

For details on contributing to this repository, see the contributing guide.

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

node-diagnostic-channel's People

Contributors

berkcent avatar ejbroeders avatar hectorhdzg avatar jackhorton avatar joshgav avatar markwolff avatar microsoftopensource avatar mike-kaufman avatar msftgits avatar mslaguana avatar sumbad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-diagnostic-channel's Issues

Add centralized error handling for the patching process

There are a bunch of different ways that patching can fail, and different levels of severity for any given patch failure:

  1. A patched function may throw due to errors introduced by the patch
  2. A patched function may throw due to errors that the patch checks for and simply forwards along to the patchee.
  3. A patched callback/event handler may throw itself
  4. A patched callback/event handler may call an original callback/event handler that throws

When the original library throws or when the user-supplied callback or event handler throws, this may be caused either by the user supplying known-invalid arguments or by a patch making incorrect changes to the user-supplied arguments.

Regardless, we should likely have a way to track these errors. Some initial notes on that:

  • We probably want to report what argument configuration caused this error to come up, but we definitely don't want to actually give all of the arguments themselves for security reasons. Perhaps we can track the types of arguments provided as a middle ground? Or, we could log everything and let the channel user decide what to do for security depending on their use case.
  • Errors coming from user-supplied callbacks and original libraries could be completely not our fault, but determining when that's the case is tough.
  • We could publish them all over a dedicated channel: channel.publish("patch-error", { err: Error, severity: number, arguments: any[]}
  • We could provide an API to hook into: channel.throw() /* from the publisher */ -> channel.catch() /* from the subscriber */

Move all publishers into a single module

Moving all publishers into a single module has the following benefits:

  • easier install/build (since we only need to install/build 2 or 3 packages, instead of a growing number based on how many pubs we have).
  • faster install/build/test
  • easier package release management/publishing

Any thoughts/preferences/counter-arguments to the above?

/cc @avanderhoorn, @joshgav, @MSLaguana

Module not found: Can't resolve '@opentelemetry/tracing'

My npm build has all of a sudden started to fail.

Error: ./node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js
Module not found: Can't resolve '@opentelemetry/tracing' in 'e:\vsts\a\4899\s\node_modules\diagnostic-channel-publishers\dist\src'

Node: 12.16.3
npm: 6.12.1

diagnostic-channel-publishers - RangeError: Maximum call stack size exceeded

Hello.

Few days ago, we upgraded our Node project from diagnostic-channel-publishers v1.0.1 to v1.0.2.

And since this upgrade, after few hours of run, this error occured :

RangeError: Maximum call stack size exceeded\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)\n at Tracer.tracer.startSpan (/home/vcap/deps/0/node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js:57:54)

I saw the last update of "azure-coretracing.pub" file which manage "@azure/core-tracing" version.
And in our project, we are in 1.0.0-preview.13 version.

Can you please help us ?

FYI, we are downgrading to 1.0.1.

name of module

Can we clarify why we're calling it node-diagnostic-source?

How about node-trace-channel or node-trace-bus ๐ŸšŒ ? "bus" is fun in my opinion ๐Ÿ˜†

Console publisher doesn't work in VSCode

VSCode has a non-standard console object, that the diagnostic channel publisher clobbers.

Patching individual methods rather than the whole object may be a solution here.

Dependancy request warnings in webpack

We pull in diagnostic-channel-publishers via applicationinsights. Since applicationinsights 2.3.0 (with diagnostic-channel-publishers 1.0.5) we have been getting the following warnings when running webpack:

WARNING in ./node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js 77:37-78
Module not found: Error: Can't resolve '@opentelemetry/instrumentation' in '***/node_modules/diagnostic-channel-publishers/dist/src'
 @ ./node_modules/diagnostic-channel-publishers/dist/src/index.js 6:15-49
 @ ./node_modules/applicationinsights/out/AutoCollection/diagnostic-channel/initialization.js 11:21-61
 @ ./node_modules/applicationinsights/out/AutoCollection/CorrelationContextManager.js 5:18-64
 @ ./node_modules/applicationinsights/out/applicationinsights.js 4:32-85

WARNING in ./node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js 78:32-89
Module not found: Error: Can't resolve '@azure/opentelemetry-instrumentation-azure-sdk' in '***/node_modules/diagnostic-channel-publishers/dist/src'
 @ ./node_modules/diagnostic-channel-publishers/dist/src/index.js 6:15-49
 @ ./node_modules/applicationinsights/out/AutoCollection/diagnostic-channel/initialization.js 11:21-61
 @ ./node_modules/applicationinsights/out/AutoCollection/CorrelationContextManager.js 5:18-64
 @ ./node_modules/applicationinsights/out/applicationinsights.js 4:32-85

When manually adding @opentelemetry/instrumentation and @azure/opentelemetry-instrumentation-azure-sdk we just get the following warning:

WARNING in ./node_modules/@opentelemetry/instrumentation/build/esm/platform/node/instrumentation.js 63:26-69
Critical dependency: the request of a dependency is an expression
 @ ./node_modules/@opentelemetry/instrumentation/build/esm/platform/node/index.js 16:0-34 16:0-34
 @ ./node_modules/@opentelemetry/instrumentation/build/esm/platform/index.js 16:0-23 16:0-23
 @ ./node_modules/@opentelemetry/instrumentation/build/esm/index.js 17:0-33 17:0-33
 @ ./node_modules/diagnostic-channel-publishers/dist/src/azure-coretracing.pub.js 77:37-78
 @ ./node_modules/diagnostic-channel-publishers/dist/src/index.js 6:15-49
 @ ./node_modules/applicationinsights/out/AutoCollection/diagnostic-channel/initialization.js 11:21-61
 @ ./node_modules/applicationinsights/out/AutoCollection/CorrelationContextManager.js 5:18-64
 @ ./node_modules/applicationinsights/out/applicationinsights.js 4:32-85

We believe this is to do with the conditional require inside azure-coretracing.pub.ts introduced here.

Console subs using winston always trackTrace as info

I've configured winston in an app with AppInsights-Nodejs and It is successfully sending telemetry to Azure AppInsights.

But it will always send such telemetry with Information Severity Level even when logging errors.

I'd have expected once the winston logger levels matched with the recently exposed app insights contracts by using custom levels, it starts sending the severity level properly. But as linked above and here, it doesn't seem to be possible.

Am I missing something here?

Winston: 'Cannot read property `level` of undefined' when Logger created without arguments

When winston is initiated without a config object:

const winston = require('winston');
exports.Logger = winston.createLogger();

It fails with:

Stack: TypeError: Cannot read property 'levels' of undefined
    at Object.patchedCreate [as createLogger] (C:\home\site\wwwroot\node_modules\diagnostic-channel-publishers\dist\src\winston.pub.js:116:35)

Related code: https://github.com/microsoft/node-diagnostic-channel/blob/master/src/diagnostic-channel-publishers/src/winston.pub.ts#L89

Seems to expect createLogger({}) as minimum however not supplying anything is a valid option and should be checked for instead of assuming that there will always be an object set.

Works correctly if supplied {} as argument to createLogger.

Making this project a standard

This project addresses a need that is common to every language. Now that efforts like OpenTelemetry are being standardized, would it make sense to also create a similar standard project for the diagnostic channel? This could also serve as a backbone to OpenTelemetry in every language, while also unblocking many more use cases in every language. The concept of a centralized bus is also simple enough that I expect it could eventually land in the standard library of many languages, and thus adoption could become very high even within libraries directly.

My understanding is that this is already implemented in Node and .NET (correct me if that's wrong). Is this something being considered?

add `test` switch to install.sh

Would be nice to be able to use the same script to just build or to build and also test. One way to do that would be to recognize a --test switch in the script and only run npm test when that's passed.

diagnostic-channel-publishers to support PgQueryStream

I've got this error when executing a query stream

TypeError: queryResult.then is not a function
    at Client.query (star-wars/node_modules/diagnostic-channel-publishers/dist/src/pg.pub.js:238:10)
    at PostgresQueryRunner.<anonymous> (star-wars/node_modules/typeorm/build/src/driver/postgres/PostgresQueryRunner.js:218:53)
    at step (star-wars/node_modules/typeorm/node_modules/tslib/tslib.js:136:27)
    at Object.next (star-wars/node_modules/typeorm/node_modules/tslib/tslib.js:117:57)
    at fulfilled (star-wars/node_modules/typeorm/node_modules/tslib/tslib.js:107:62)

This occurs when I import applicationinsights module without even setup and start app insight

diagnostic-channel-publisher to support "pg-copy-streams"

When executing a pg_copy_stream:

        const pool = new Pool(config.database_config);
        const copyFrom = require('pg-copy-streams').from;
        const { Readable } = require('stream');
        const createCsvWriter = require('csv-writer').createArrayCsvStringifier
        [...]
        var target = db.query(copyFrom(`COPY temptable (a,b,c) FROM STDIN DELIMITER ';' CSV HEADER':''}`));
        var source = Readable.from(await csvWriter.stringifyRecords(table_data));
        source.pipe(target);

The target variable is not of type Promise it is of type CopyStreamQuery extending Writeable. This of course ends in the error:

TypeError: queryResult.then is not a function
    at Client.query (D:\home\site\wwwroot\node_modules\diagnostic-channel-publishers\dist\src\pg.pub.js:245:18)

versions:

    "applicationinsights": "^1.7.5",
    "pg": "^8.2.1",
    "csv-writer": "^1.6.0",
    "pg-copy-streams": "^5.1.0"

"applicationinsights" pull dependency to:

        "diagnostic-channel": "0.2.0",
        "diagnostic-channel-publishers": "^0.3.4"

Can this be modeled on top of async hooks

Things like asynchronous operations at the very least could be expressed as (virtual) async resources. An interesting question would be if this is sufficient to express something like a "diagnostics channel" by filtering for specific async_hooks resources.

Investigate diagnostic channel/patchee/node version matrices

As it stands right now, we are taking a lot of assumptions on how diagnostic channel and our default publishers work across different scenarios. We should set up some testing matrix across the following axes:

  • node versions
  • channel versions
  • publisher versions
    • patched module versions
  • node projects containing multiple versions of the above across different modules (testing the concept of a global channel)

work to be done

Initial cut, will open issues on below as appropriate.

  • rename to node-diagnostic-source
  • rename packages to diagnostic-source (PR #3)
  • naming convention for publisher modules? (e.g., console-diagnostic-pub? console-diagnostic-source?...)
  • test plan for how we don't break AI
  • test plan for how we don't break glimpse
  • setup CI
  • get CI running across multiple node versions
  • get CI running across multiple module versions
  • figure out matrix above (what node versions X what module versions)
  • don't write build output into source tree (PR #1)
  • renaming magic variable used for auto-load (no longer needed per PR #15)
  • figure out publishing to NPM
  • root level readme

Glimpse:

  • remove glimpse tracing APIs and replace with channel
    • add hrtime property to event
  • ...
  • [ ]

AI:

  • hook this up into AI SDK
  • move subs out

Winston: "Cannot read property 'levels' of undefined" when Logger created without arguments

I have a node-based project running as a linux Azure App Service (with Application Insights enabled).
In my application, when winston is initiated without a config object:

const winston = require('winston')
const logger = winston.createLogger() // fails
module.exports = logger

It fails:

[INFO]    _____
[INFO]    /  _  \ __________ _________   ____
[INFO]   /  /_\  \___   /  |  \_  __ \_/ __ \
[INFO]  /    |    \/    /|  |  /|  | \/\  ___/
[INFO]  \____|__  /_____ \____/ |__|    \___  >
[INFO]          \/      \/                  \/
[INFO]  A P P   S E R V I C E   O N   L I N U X
[INFO]
[INFO]  Documentation: http://aka.ms/webapp-linux
[INFO]  NodeJS quickstart: https://aka.ms/node-qs
[INFO]  NodeJS Version : v16.8.0
[INFO]
[ERROR]  /agents/node/node_modules/diagnostic-channel-publishers/dist/src/winston.pub.js:116
[ERROR]          var levels = arguments[0].levels || originalWinston.config.npm.levels;
[ERROR]                                    ^
[ERROR]
[ERROR]  TypeError: Cannot read property 'levels' of undefined
[ERROR]      at Object.patchedCreate [as createLogger] (/agents/node/node_modules/diagnostic-channel-publishers/dist/src/winston.pub.js:116:35)
[ERROR]      at Object.<anonymous> (/home/site/wwwroot/server/utils/logger.js:19:24)
[ERROR]      at Module._compile (node:internal/modules/cjs/loader:1101:14)
[ERROR]      at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
[ERROR]      at Module.load (node:internal/modules/cjs/loader:981:32)
[ERROR]      at Function.Module._load (node:internal/modules/cjs/loader:822:12)
[ERROR]      at Module.require (node:internal/modules/cjs/loader:1005:19)
[ERROR]      at Module.patchedRequire [as require] (/agents/node/node_modules/diagnostic-channel/dist/src/patchRequire.js:15:46)
[ERROR]      at require (node:internal/modules/cjs/helpers:94:18)
[ERROR]      at Object.<anonymous> (/home/site/wwwroot/server/router/api.js:4:16)
[ERROR]  npm info lifecycle [email protected]~start: Failed to exec start script
[ERROR]  npm ERR! code ELIFECYCLE
[ERROR]  npm ERR! errno 1
[ERROR]  npm ERR! [email protected] start: `node server.js`
[ERROR]  npm ERR! Exit status 1
[ERROR]  npm ERR!
[ERROR]  npm ERR! Failed at the [email protected] start script.
[ERROR]  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Even though passing nothing is considered valid by Winston: https://github.com/winstonjs/winston/blob/master/index.d.ts#L184

// index.d.ts
let createLogger: (options?: LoggerOptions) => Logger;

Works correctly if empty object {} supplied as argument to createLogger:

const winston = require('winston')
const logger = winston.createLogger({}) // succeeds
module.exports = logger

Support for mongo 3

When possible, support for mongo version 3 and higher would be excellent.

Monkey-patch for Winston3 publishes too much

The Winston patch publishes on the diagnostic channel all logs that Winston collects. I would expect as an end-user that only messages above the configured Winston log level get published.

Current situation:

import * as appInsights from 'applicationinsights';
import * as winston from 'winston';

const logger = winston.createLogger({
  level: 'warn',
});

appInsights.setup();
appInsights.start();

logger.debug('This should not trigger a publish on the diagnostic-channel - but it does');

Links:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.