Skip to content

Commit

Permalink
rename build to compose
Browse files Browse the repository at this point in the history
applies to ts interfaces as well
  • Loading branch information
paed01 committed Nov 10, 2023
1 parent 51bc869 commit be5f58c
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 85 deletions.
97 changes: 95 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Build transport stream function.

- `opts`:
* `track(chunk)`: track function called with Telemetry client context
- `chunk`: [Telemetry:ish](#telemetrish-object) object
* `connectionString`: Application Insights connection string or instrumentation key
* `config`: optional Application Insights Telemetry client config
* `destination`: optional destination stream, makes build ignore the above options
Expand All @@ -39,6 +40,98 @@ Build transport stream function.

### `class TelemetryTransformation(options[, config])`

Telemetry transformation stream. Transforms pino log record to Telemetry:ish object.
Telemetry transformation stream. Transforms pino log record to [Telemetry:ish](#telemetrish-object) object.

### `class FakeApplicationInsigths()`
#### Telemetrish object

- `severity`: pino log level mapped to application insights `Contracts.SeverityLevel`
- `msg`: log message string
- `properties`: telemetry properties object, filtered through ignore keys
- `exception?`: logged Error if any
- `[k: string]`: any other properties

### `class FakeApplicationInsights(setupString)`

Intercept calls to application insights.

- `constructor(setupString);`
* `setupString`: Fake application insights connection string
- `expectMessageData()`: Expect tracked message, returns [`Promise<FakeCollectData>`](#fakecollectdata)
- `expectEventData()`: Expect tracked event, returns [`Promise<FakeCollectData>`](#fakecollectdata)
- `expectExceptionData()`: Expect tracked exception, returns [`Promise<FakeCollectData>`](#fakecollectdata)
- `expectEventType(telemetryType: string)`: Expect tracked telemetry type, returns [`Promise<FakeCollectData>`](#fakecollectdata)
* `telemetryType`: Telemetry type string
- `expect(count = 1)`: Expect tracked telemetrys, returns list of [`Promise<FakeCollectData[]>`](#fakecollectdata)
* `count`: wait for at least tracked telemetrys before returning, default is 1
- `reset()`: Reset expected faked Application Insights calls, calls `nock.cleanAll`
- properties:
* `client`: TelemetryClient, used to get endpoint URL
* `_endpointURL`: endpoint URL
* `_scope`: nock Scope

#### Example

```js
import { randomUUID } from 'node:crypto';
import { pino } from 'pino';

import compose from '@0dep/pino-applicationinsights';
import { FakeApplicationInsights } from '@0dep/pino-applicationinsights/fake-applicationinsights.js';

describe('test logger', () => {
const connectionString = `InstrumentationKey=${randomUUID()};IngestionEndpoint=https://ingestion.local;LiveEndpoint=https://livemonitor.local/`;

let fakeAI;
before(() => {
fakeAI = new FakeApplicationInsights(connectionString);
});
after(() => {
fakeAI.reset();
});

it('log event track event', async () => {
const transport = compose({
track(chunk) {
const { time, properties } = chunk;
this.trackEvent({ name: 'my event', time, properties, measurements: { logins: 1 } });
},
connectionString,
config: { maxBatchSize: 1, disableStatsbeat: true },
});
const logger = pino(transport);

const expectMessage = fakeAI.expectEventData();

logger.info({ bar: 'baz' }, 'foo');

const msg = await expectMessage;

expect(msg.body.data.baseData).to.deep.include({
properties: { bar: 'baz' },
measurements: { logins: 1 },
name: 'my event',
});

transport.destroy();
});
});
```

#### `FakeCollectData`

- `uri`: string;
- `method`: string;
- `headers`: request headers object
- `body`:
* `ver`: some version number
* `sampleRate`: sample rate number
* `tags`: object with tags
* `data`:
- `baseType`: telemetry type string
- `baseData`:
* `ver`: number
* `properties`: telemetry properties object
* `[x: string]`: any other telemetry
- `iKey`: instrumentation key string
- `name`: string
- `time`: log time
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
},
"engines": {
"node": ">= 16"
"node": ">=16"
},
"scripts": {
"test:ts": "mocha --config test/typescript/.mocharc.json",
Expand Down
2 changes: 2 additions & 0 deletions src/fake-applicationinsights.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export class FakeApplicationInsights {
*/
constructor(setupString) {
const client = this.client = new TelemetryClient(setupString);
client.getStatsbeat().enable(false);

const endpointURL = this._endpointURL = new URL(client.config.endpointUrl);

this._endpointPathname = endpointURL.pathname;
Expand Down
8 changes: 5 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class TelemetryTransformation extends Transform {

/**
* Compose Application Insights pino transport
* @param {import('../types/interfaces.js').ConnectionStringBuildConfig | import('../types/interfaces.js').DestinationBuildConfig} opts - transport options
* @param {import('../types/interfaces.js').ConnectionStringComposeConfig | import('../types/interfaces.js').DestinationComposeConfig} opts - transport options
* @param {typeof TelemetryTransformation} [Transformation] - optional Telemetry transformation stream
* @returns {ReturnType<typeof import('pino-abstract-transport')>}
*/
Expand All @@ -118,14 +118,16 @@ export default function compose(opts, Transformation = TelemetryTransformation)

/** @type {Writable | Transform} */
let destination;
let client;
if (opts.destination) {
if (typeof opts.destination.write !== 'function') throw new TypeError('destination must be a writable stream');
destination = opts.destination;
} else {
client = new TelemetryClient(opts.connectionString);
const client = new TelemetryClient(opts.connectionString);

if (opts.config) {
if (opts.config.disableStatsbeat) {
client.getStatsbeat().enable(false);
}
Object.assign(client.config, opts.config);
}

Expand Down
6 changes: 3 additions & 3 deletions test/commonjs/log-transport-test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const { randomUUID } = require('node:crypto');
const pino = require('pino');

const build = require('../../lib/index.cjs');
const compose = require('../../lib/index.cjs');
const { FakeApplicationInsights } = require('../../lib/fake-applicationinsights.cjs');

describe('log transport', () => {
Expand All @@ -18,13 +18,13 @@ describe('log transport', () => {
});

it('connection string', async () => {
const transport = build({
const transport = compose({
track(chunk) {
const { time, severity, msg: message, properties } = chunk;
this.trackTrace({ time, severity, message, properties });
},
connectionString,
config: { maxBatchSize: 1 },
config: { maxBatchSize: 1, disableStatsBeat: true },
});
const logger = pino(transport);

Expand Down
2 changes: 2 additions & 0 deletions test/helpers/setup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import nock from 'nock';
import chai from 'chai';

process.env.NODE_ENV = 'test';

globalThis.expect = chai.expect;

nock.enableNetConnect(/127\.0\.\.1/);

0 comments on commit be5f58c

Please sign in to comment.