Skip to content

Commit

Permalink
fix: Logging to stdout in Cloud Run creates a JSON object as "message" (
Browse files Browse the repository at this point in the history
#644)

* fix: Logging to stdout in Cloud Run creates a JSON object as "message"

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
losalex and gcf-owl-bot[bot] authored Jul 18, 2022
1 parent 0455178 commit 41eaaa8
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .readme-partials.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ body: |-
It is recommended to set `redirectToStdout: true` in serverless environments like Cloud Functions since it could
decrease logging record loss upon execution termination - since all logs are written to `process.stdout` those
would be picked up by the Cloud Logging Agent running in Google Cloud managed environment.
Note that there is also a `useMessageField` option which controls if "message" field is used to store
structured, non-text data inside `jsonPayload` field when `redirectToStdout` is set. By default `useMessageField` is always `true`.
```js
// Imports the Google Cloud client library for Bunyan
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ The agent can parse structured logs printed to `process.stdout` and capture addi
It is recommended to set `redirectToStdout: true` in serverless environments like Cloud Functions since it could
decrease logging record loss upon execution termination - since all logs are written to `process.stdout` those
would be picked up by the Cloud Logging Agent running in Google Cloud managed environment.
Note that there is also a `useMessageField` option which controls if "message" field is used to store
structured, non-text data inside `jsonPayload` field when `redirectToStdout` is set. By default `useMessageField` is always `true`.

```js
// Imports the Google Cloud client library for Bunyan
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"precompile": "gts clean"
},
"dependencies": {
"@google-cloud/logging": "^10.0.2",
"@google-cloud/logging": "^10.1.1",
"google-auth-library": "^8.0.2"
},
"devDependencies": {
Expand Down
11 changes: 10 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import * as types from './types/core';

import {ApiResponseCallback} from '@google-cloud/logging/build/src/log';
import {LogSeverityFunctions} from '@google-cloud/logging/build/src/utils/log-common';
import {LogSyncOptions} from '@google-cloud/logging/build/src/log-sync';

// Map of Stackdriver logging levels.
const BUNYAN_TO_STACKDRIVER: Map<number, string> = new Map([
Expand Down Expand Up @@ -177,6 +178,7 @@ export class LoggingBunyan extends Writable {
private defaultCallback?: ApiResponseCallback;
cloudLog: LogSeverityFunctions;
redirectToStdout: boolean;

constructor(options?: types.Options) {
options = options || {};
super({objectMode: true});
Expand All @@ -195,7 +197,14 @@ export class LoggingBunyan extends Writable {
maxEntrySize: options.maxEntrySize || 250000,
});
} else {
this.cloudLog = new Logging(options).logSync(this.logName);
const logSyncOptions: LogSyncOptions = {
useMessageField: options.useMessageField ?? true,
};
this.cloudLog = new Logging(options).logSync(
this.logName,
undefined,
logSyncOptions
);
}

// serviceContext.service is required by the Error Reporting
Expand Down
7 changes: 7 additions & 0 deletions src/types/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export interface Options {
* agent. Redirected logs are formatted as one line Json string following the structured logging guidelines.
*/
redirectToStdout?: boolean;

/**
* Boolean flag indicating if "message" field should be used to store structured,
* non-text data inside jsonPayload field. This flag applies only when {@link Options#redirectToStdout} is set.
* By default this value is true
*/
useMessageField?: boolean;
}

export interface MonitoredResource {
Expand Down
10 changes: 10 additions & 0 deletions system-test/logging-bunyan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ describe('LoggingBunyan', function () {
assert.ok(loggingBunyan.cloudLog instanceof LogSync);
});

it('should create LoggingBunyan with LogSync and useMessageField is off', () => {
const loggingBunyan = new LoggingBunyan({
logName: LOG_NAME,
redirectToStdout: true,
useMessageField: false,
});
assert.ok(loggingBunyan.cloudLog instanceof LogSync);
assert.ok(loggingBunyan.cloudLog.useMessageField_ === false);
});

it('should write diagnostic entry', async () => {
instrumentation.setInstrumentationStatus(false);
const start = Date.now();
Expand Down

0 comments on commit 41eaaa8

Please # to comment.