googleapis / nodejs-logging-bunyan

Node.js client integration between Stackdriver Logging and Bunyan.
https://cloud.google.com/logging/
Apache License 2.0
63 stars 34 forks source link

Sending a log when no internet exception #530

Closed faljabi closed 2 years ago

faljabi commented 3 years ago

Hi,

I am getting this exception when logging without internet after like 10mins and crashing my server as shown below:

GoogleError: Total timeout of API google.logging.v2.LoggingServiceV2 exceeded 600000 milliseconds before any response was received. at repeat (D:\SmartCart\SmartCart+\android\server\node_modules\google-gax\build\src\normalCalls\retries.js:66:31) at Timeout._onTimeout (D:\SmartCart\SmartCart+\android\server\node_modules\google-gax\build\src\normalCalls\retries.js:101:25) at listOnTimeout (node:internal/timers:557:17) at processTimers (node:internal/timers:500:7) Emitted 'error' event on LoggingBunyan instance at: at emitErrorNT (node:internal/streams/destroy:188:8) at emitErrorCloseNT (node:internal/streams/destroy:153:3) at processTicksAndRejections (node:internal/process/task_queues:81:21) { code: 4 }

I tried logger.on('error') and it did not catch it. Could you please advise on how to catch this exception for me to log on a local file instead for example when no internet?

0xSage commented 3 years ago

Hi @faljabi, how did you configure the logger? By default, it will log to Google's Cloud Logging api endpoint. One way to sporadically switch it off, is by setting the level to a point where no logs will be emitted.

The logs are bundled then batch-sent asynchronously which is why you can't do logger.on('error')

faljabi commented 3 years ago

Hello @nicoleczhu,

This is how I configured my logger:

const config = require('config');
const { LoggingBunyan } = require('@google-cloud/logging-bunyan');
const bunyan = require('bunyan');

process.env.GOOGLE_APPLICATION_CREDENTIALS = config.get('logging.googleCloud.serviceAccount.filePath');

const loggingBunyan = new LoggingBunyan({
    logName: config.get('server.name')
});

const logger = bunyan.createLogger({
    name: config.get('server.name'),
    streams: [{
        stream: process.stdout,
        level: 'info'
    },
    loggingBunyan.stream('info')]
});

module.exports = logger;

I don't want to switch off rather I expected the bunyan logger to emit errors that I can catch or it will crash my node server.

0xSage commented 3 years ago

Hi @faljabi , if you configured loggingBunyan, you need an internet connection. The logs are getting written asynchronously, so you don't have control around the execution flow. You can see a related comment here.

What's your use case exactly? Maybe you can write a wrapper/switchcase to only instrument the loggingBunyan adapter when your app has an internet connection.

faljabi commented 3 years ago

Hi @nicoleczhu,

Thank you for your quick reply and suggestion I will consider it.

I understand that I need an internet connection and I understand that logs are written asynchronously. My use case is that I installed NodeJS via Termux on an Android device. This android device is installed on a smart shopping cart that may lose internet connection at anytime. I just expected that I can catch errors emitted from the logger where it is crashing the nodejs server thus cart is malfunctional in that case. So I have two options:

I am suggesting that the logger should have logger.on('error') instead of catching that error on the nodejs process itself. What do you think?

0xSage commented 3 years ago

I think your suggestion makes a lot of sense. IMO, "a client library should never panic". There's an work in progress on how these libraries should universally report debug logs: https://github.com/feywind/node-debug-logging

I'm monitoring its progress and will integrate it with this library. Or apply a temporary solution here to avoid crashing your node server. Marking this as a feature request

losalex commented 2 years ago

@faljabi, sorry it took so long to get back to you. I believe this issue should be resolved by #597 - the solution is to provide a global callback which could be used to process responses and catch any errors. There is a sample here which could be used as reference on how such callback can be provided. I am closing this issue for now and please feel free to reopen/comment in case if you have more concerns or feedback.

ghost commented 2 years ago

@losalex @0xSage, thank you so much for your efforts. Exactly what I needed.