2.1.1 • Published 5 months ago

google-cloud-structured-logs v2.1.1

Weekly downloads
1
License
ISC
Repository
github
Last release
5 months ago

Google Cloud Structured Logs

Release V2!!!

This is a little package to simplify structured logging in Google Cloud Platform.

This package helps to track useful information from operation context and all the information needed to track not only one service operation else the ability to track interactions between services using a trace to follow every each log generated during consecutive services communications.

Installation

npm install --save google-cloud-structured-logs

Simple Example

A simple implementation can be like this, you need to call the library, create a log Object with the process or service name and set a new context. After that you can log something passing this context and your logs will be beautiful.

const logger = require('google-cloud-structured-logs');
const log = logger('My Service Name');

const ctx = log.newCtx({ task: 'Task Name'});
const exampleOperationResult = {foo: 'bar'};
log.info(ctx, 'Log message, it can be an object', exampleOperationResult);

This simple example will generate this output in console and in stackdriver logging.

{
    "name": "ms-boilerplate",
    "hostname": "MacBook-Air-de-user.local",
    "pid": 38126,
    "level": 50,
    "severity": 500,
    "trace": null,
    "spanId": "f985523941070851",
    "startAt": "2023-06-19T03:21:49.712Z",
    "time": "2023-06-19T03:21:49.720Z",
    "task": "validaIdentidad",
    "message": null,
    "parameters": [],
    "error": null,
    "result": null,
    "duration": 8,
    "httpRequest": null,
    "msg": "",
    "v": 0
}

The following example illustrate how the logger interpret the request and response parameters generated by express.js 4.x

{
    "name": "ms-boilerplate",
    "hostname": "MacBook-Air-de-user.local",
    "pid": 38126,
    "level": 50,
    "severity": 500,
    "trace": null,
    "spanId": "f985523941070851",
    "startAt": "2023-06-19T03:21:49.712Z",
    "time": "2023-06-19T03:21:49.720Z",
    "task": "validaIdentidad",
    "message": null,
    "parameters": [],
    "error": {
        "code": 400,
        "success": false,
        "errors": [
            {
                "detail": "param1",
                "description": "Is Required"
            },
            {
                "detail": "param2",
                "description": "Is Required"
            }
        ]
    },
    "result": null,
    "duration": 8,
    "httpRequest": {
        "requestMethod": "GET",
        "requestUrl": "/validaIdentidad/161358533?key=123",
        "requestSize": "",
        "status": 400,
        "responseSize": "",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
        "remoteIp": null,
        "serverIp": null,
        "referer": "",
        "latency": "0.01s",
        "cacheLookup": null,
        "cacheHit": null,
        "cacheValidatedWithOriginServer": null,
        "cacheFillBytes": "",
        "protocol": "http"
    },
    "msg": "",
    "v": 0
}

In this example we can see the duration value calculated between the startAt time and the current log time.

setTimeout(() => {
    log.info(ctx, '300 ms after');
}, 300)

The previous log will generate this output, please see duration value, that metric can be very useful to get insights from some external services requests o bd queries.

{
    "name": "My Service Name",
    "hostname": "user-MacBook-Pro.local",
    "pid": 98231,
    "level": 30,
    "severity": 200,
    "trace": "0e6efb4f-d7bb-4cbb-9161-2147537cc9b7",
    "spanId": "f985523941070851",
    "startAt": "2020-07-28T20:38:27.261Z",
    "time": "2020-07-28T20:38:27.568Z",
    "task": "Task Name",
    "message": "300 ms after",
    "parameters": null,
    "error": null,
    "result": null,
    "duration": 307,
    "httpRequest": null,
    "msg": "",
    "v": 0
}

Passing trace

When you want to trace the execution between your services, you can pass as parameter the trace. To do this we only need to pass the trace in the context creation with newCtx

const ctx = log.newCtx({ task: 'Task Name', trace: 'some trace vealue'} );
log.info(ctx, 'This log will reuse a receibed trace');

if you want to set trace after to create the new Context use the setTrace method.

log.setTrace("Some Trace Value");

Using context

As you can see in previous examples the context is very important to log with simplicity and it can enable you to extend your tracing between functions, methods even to other services.

Creating context in sub functions or Promises

const logger = require('google-cloud-structured-logs');
const log = logger('My Service Name');

const ctx = log.newCtx('Task Name');
const res = {foo: 'bar'};
log.info(ctx,"Hi", res);

const addPromise = (prevCtx, val1 , val2 ) => new Promise((resolve) => {
    let _ctx = log.setCtx(prevCtx , 'addPromise', [val1, val2]);
    const result = val1 + val2;
    log.info(_ctx, 'The result is', result);
    resolve(result);
    // Please in the real world you must implement reject 
});

addPromise(ctx, 5, 15).then((result) => {
    log.info(ctx,"And the result is......", result);
});
{
    "name": "My Service Name",
    "hostname": "user-MacBook-Pro.local",
    "pid": 1499,
    "level": 30,
    "trace": "9d130cdb-5413-422e-867e-f2205f66d9ac",
    "spanId": "f985523941070851",
    "startAt": "2020-07-28T22:09:34.923Z",
    "time": "2020-07-28T22:09:34.923Z",
    "task": "Task Name",
    "message": "Hi",
    "parameters": null,
    "error": null,
    "result": {
        "foo": "bar"
    },
    "duration": 0,
    "msg": "",
    "v": 0
}
{
    "name": "My Service Name",
    "hostname": "user-MacBook-Pro.local",
    "pid": 1499,
    "level": 30,
    "trace": "9d130cdb-5413-422e-867e-f2205f66d9ac",
    "spanId": "f985523941070851",
    "startAt": "2020-07-28T22:09:34.925Z",
    "time": "2020-07-28T22:09:34.925Z",
    "task": "addPromise",
    "message": "The result is",
    "parameters": [
        5,
        15
    ],
    "error": null,
    "result": 20,
    "duration": 0,
    "msg": "",
    "v": 0
}
{
    "name": "My Service Name",
    "hostname": "user-MacBook-Pro.local",
    "pid": 1499,
    "level": 30,
    "trace": "9d130cdb-5413-422e-867e-f2205f66d9ac",
    "spanId": "f985523941070851",
    "startAt": "2020-07-28T22:09:34.923Z",
    "time": "2020-07-28T22:09:34.929Z",
    "task": "Task Name",
    "message": "And the result is......",
    "parameters": null,
    "error": null,
    "result": 20,
    "duration": 6,
    "msg": "",
    "v": 0
}

Managing Uncaught Exceptions

When your code generate an uncaughtException it will be captured automatically by the logger and logged in the structured format and bring to you some additional information about CPU and RAM usage, the execution/service uptime and some more.

{
    "name": "uncaughtException",
    "hostname": "user-MacBook-Pro.local",
    "pid": 1853,
    "level": 60,
    "trace": "c2c156e8-0427-458c-87dc-5d7392d7ed7d",
    "spanId": "f985523941070851",
    "startAt": "2020-07-28T22:20:47.054Z",
    "time": "2020-07-28T22:20:47.055Z",
    "task": "uncaughtException",
    "message": null,
    "parameters": {
        "cpuUsage": {
            "user": 461223,
            "system": 115246
        },
        "memoryUsage": {
            "rss": 61190144,
            "heapTotal": 33357824,
            "heapUsed": 14655688,
            "external": 1640654,
            "arrayBuffers": 102030
        },
        "uptime": 1.726650084,
        "resourceUsage": {
            "userCPUTime": 461373,
            "systemCPUTime": 115260,
            "maxRSS": 61517824,
            "sharedMemorySize": 0,
            "unsharedDataSize": 0,
            "unsharedStackSize": 0,
            "minorPageFault": 15846,
            "majorPageFault": 4044,
            "swappedOut": 0,
            "fsRead": 0,
            "fsWrite": 0,
            "ipcSent": 7,
            "ipcReceived": 8,
            "signalsCount": 1,
            "voluntaryContextSwitches": 842,
            "involuntaryContextSwitches": 1721
        }
    },
    "error": {
        "message": "Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.",
        "stack": "Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.\n    at GoogleAuth.getApplicationDefaultAsync (/build/src/auth/googleauth.js:160:19)\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)\n    at async GoogleAuth.getClient (/build/src/auth/googleauth.js:502:17)\n    at async GrpcClient._getCredentials (/node_modules/google-gax/build/src/grpc.js:92:24)\n    at async GrpcClient.createStub (/node_modules/google-gax/build/src/grpc.js:213:23)",
        "name": "Error"
    },
    "result": null,
    "duration": 1,
    "msg": "",
    "v": 0
}
2.1.1

5 months ago

2.1.0

8 months ago

2.0.0

9 months ago

1.1.0

3 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago