Skip to content

Commit 14bdea4

Browse files
feat: Add support for library instrumentation (#631)
* feat: Add support for library instrumentation * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix lint error * Remove redundant console log * Address PR comments Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 45a1b21 commit 14bdea4

3 files changed

Lines changed: 82 additions & 1 deletion

File tree

handwritten/logging-bunyan/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"precompile": "gts clean"
5252
},
5353
"dependencies": {
54-
"@google-cloud/logging": "^10.0.0",
54+
"@google-cloud/logging": "^10.0.2",
5555
"google-auth-library": "^8.0.2"
5656
},
5757
"devDependencies": {

handwritten/logging-bunyan/src/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616

1717
import {Writable} from 'stream';
1818
import * as express from './middleware/express';
19+
import {
20+
setInstrumentationStatus,
21+
createDiagnosticEntry,
22+
} from '@google-cloud/logging/build/src/utils/instrumentation';
23+
import path = require('path');
1924

2025
// Export the express middleware as 'express'.
2126
export {express};
@@ -64,6 +69,9 @@ export const LOGGING_SPAN_KEY = 'logging.googleapis.com/spanId';
6469
*/
6570
export const LOGGING_SAMPLED_KEY = 'logging.googleapis.com/trace_sampled';
6671

72+
// The variable to hold cached library version
73+
let libraryVersion: string;
74+
6775
/**
6876
* Gets the current fully qualified trace ID when available from the
6977
* @google-cloud/trace-agent library in the LogEntry.trace field format of:
@@ -426,6 +434,24 @@ export class LoggingBunyan extends Writable {
426434
* @param callback The callback supplied by Writable.write
427435
*/
428436
_writeCall(entries: Entry | Entry[], callback: Function) {
437+
// First create instrumentation record if it is never written before
438+
const alreadyWritten = setInstrumentationStatus(true);
439+
if (!alreadyWritten) {
440+
let instrumentationEntry = createDiagnosticEntry(
441+
'nodejs-bunyan',
442+
this.getNodejsLibraryVersion()
443+
);
444+
// Update instrumentation record resource and logName
445+
instrumentationEntry.metadata.resource = this.resource;
446+
instrumentationEntry.metadata.severity = 'INFO';
447+
instrumentationEntry = (
448+
this.redirectToStdout
449+
? (this.cloudLog as LogSync)
450+
: (this.cloudLog as Log)
451+
).entry(instrumentationEntry.metadata, instrumentationEntry.data);
452+
entries = Array.isArray(entries) ? entries : [entries];
453+
entries.push(instrumentationEntry);
454+
}
429455
if (this.redirectToStdout) {
430456
(this.cloudLog as LogSync).write(entries);
431457
// The LogSync class does not supports callback. However if callback provided and
@@ -435,6 +461,22 @@ export class LoggingBunyan extends Writable {
435461
(this.cloudLog as Log).write(entries, this.generateCallback(callback));
436462
}
437463
}
464+
465+
/**
466+
* Method used to retrieve the current logging-bunyan library version
467+
* @returns The version of this library
468+
*/
469+
getNodejsLibraryVersion() {
470+
if (libraryVersion) {
471+
return libraryVersion;
472+
}
473+
libraryVersion = require(path.resolve(
474+
__dirname,
475+
'../../',
476+
'package.json'
477+
)).version;
478+
return libraryVersion;
479+
}
438480
}
439481

440482
module.exports.BUNYAN_TO_STACKDRIVER = BUNYAN_TO_STACKDRIVER;

handwritten/logging-bunyan/system-test/logging-bunyan.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ import {Logging, LogSync} from '@google-cloud/logging';
2525
const logging = new Logging();
2626
import {LoggingBunyan} from '../src/index';
2727
import delay from 'delay';
28+
import * as instrumentation from '@google-cloud/logging/build/src/utils/instrumentation';
2829

2930
const WRITE_CONSISTENCY_DELAY_MS = 90000;
31+
const MESSAGE = 'Diagnostic test';
3032

3133
const UUID = uuid.v4();
3234
function logName(name: string) {
@@ -55,6 +57,43 @@ describe('LoggingBunyan', function () {
5557
assert.ok(loggingBunyan.cloudLog instanceof LogSync);
5658
});
5759

60+
it('should write diagnostic entry', async () => {
61+
instrumentation.setInstrumentationStatus(false);
62+
const start = Date.now();
63+
logger.info(MESSAGE);
64+
const entries = await pollLogs(
65+
LOG_NAME,
66+
start,
67+
2,
68+
WRITE_CONSISTENCY_DELAY_MS
69+
);
70+
assert.strictEqual(entries.length, 2);
71+
let isDiagnosticPresent = false;
72+
entries.forEach(entry => {
73+
assert.ok(entry.data);
74+
if (
75+
Object.prototype.hasOwnProperty.call(
76+
entry.data,
77+
instrumentation.DIAGNOSTIC_INFO_KEY
78+
)
79+
) {
80+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
81+
const info = (entry.data as any)[instrumentation.DIAGNOSTIC_INFO_KEY][
82+
instrumentation.INSTRUMENTATION_SOURCE_KEY
83+
];
84+
assert.equal(info[0].name, 'nodejs');
85+
assert.ok(info[0].version.includes('.'));
86+
assert.equal(info[1].name, 'nodejs-bunyan');
87+
assert.ok(info[1].version.includes('.'));
88+
isDiagnosticPresent = true;
89+
} else {
90+
const data = entry.data as {message: string};
91+
assert.ok(data.message.includes(MESSAGE));
92+
}
93+
});
94+
assert.ok(isDiagnosticPresent);
95+
});
96+
5897
it('should properly write log entries', async function () {
5998
this.retries(3);
6099
const timestamp = new Date();

0 commit comments

Comments
 (0)