Git Product home page Git Product logo

logger-nodejs's Introduction

resurfaceio-logger-nodejs

Easily log API requests and responses to your own security data lake.

npm CodeFactor License Contributing

Contents

Requires Node.js 10.x or later, and Axios http client. No other dependencies to conflict with your app.

npm install resurfaceio-logger --save

After installing the module, add a HttpLoggerForExpress instance to your app, after any body parsers in use.

const express = require('express');
const app = express();

// add body parsers

const resurfaceio = require('resurfaceio-logger');
resurfaceio.HttpLoggerForExpress.add(app, {
    url: 'http://localhost:7701/message', 
    rules: 'include debug'
});

// define routes

After installing the module, add a HttpLoggerForKoa instance to your app, after any body parsers in use.

const Koa = require('koa');
const app = new Koa();

// add body parsers

const resurfaceio = require('resurfaceio-logger');
resurfaceio.HttpLoggerForKoa.add(app, {
    url: 'http://localhost:7701/message', 
    rules: 'include debug'
});

After installing the module, add a HttpLoggerForExpress instance before calling applyMiddleware.

const app = express();

const resurfaceio = require('resurfaceio-logger');
resurfaceio.HttpLoggerForExpress.add(app, {
    url: 'http://localhost:7701/message', 
    rules: 'include debug'
});

const server = new ApolloServer({ ... });

server.applyMiddleware({ app });

After installing the module, create a logger and call it from the routes of interest.

const express = require('express');
const app = express();

const resurfaceio = require('resurfaceio-logger');
const logger = new resurfaceio.HttpLogger({
    url: 'http://localhost:7701/message',
    rules: 'include debug'
});

app.get('/', function (request, response) {
    response.render('pages/index', function (e, html) {
        response.status(200).send(html);
        resurfaceio.HttpMessage.send(logger, request, response, html);
    });
});

Loggers can be directly integrated into your application using our API. This requires the most effort compared with the options described above, but also offers the greatest flexibility and control.

API documentation

Loggers always have an active set of rules that control what data is logged and how sensitive data is masked. All of the examples above apply a predefined set of rules (include debug), but logging rules are easily customized to meet the needs of any application.

Logging rules documentation


© 2016-2024 Graylog, Inc.

logger-nodejs's People

Contributors

anyesh avatar monrax avatar robdickinson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

logger-nodejs's Issues

Axios client middleware

Research and create middleware that works from the client side, to record calls made to a remote API.

axios.interceptors.response.use(new AxiosMiddleware(url, rules));
axios.interceptors.response.use((response) => {
    return response;
  }, (error) => {
    let response = error.response;
    console.log(response.config);
    console.log(response.request);
  });

Custom fields

Add support for custom fields. This introduces breaking changes since the HttpMessage.send signature must be modified to accept custom fields. The custom fields themselves should be added to the message after rules have been applied in HttpLogger.submit_if_passing. See the logger-go implementation.

Remove valid-url dependency

This is breaking on npm version 5, and we barely depend on this. Let's copy out the code on which we depend and remove the module dependency (but keep the license notice and clearly mark the copied code as originating from valid-url).

Timeouts under test

Sometimes the node logger breaks like this under test:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

Tweaks to Express logger

  • check that logger is enabled before doing anything
  • use format/submit over log (to avoid one extra enabled check)
  • format code to better match HttpLoggerForServlets

NDJSON batching support

Add message batching to the background submission feature, using NDJSON. We can follow the logger-go implementation, in order to keep loggers consistent across languages.

Protocol and hostname are not parsed from url for HttpRequestImpl

The example that uses mock implementations in API.md results in an incomplete message that is ultimately dropped by the Resurface DB. This is due to the request_url field being skipped as both request.protocol and request.hostname are not present in the mock request instance.

How to reproduce?

// define request to log
const request = new HttpRequestImpl();
request.method = 'GET';
request.url = 'http://resurface.io';

// define response to log
const response = new HttpResponseImpl();
response.statusCode = 200;

// build JSON message
let msg = HttpMessage.build(request, response);

console.log(msg) // no request_url detail present in JSON

HttpMessage.send(logger, request, response); // this results in the request down below

//POST /message HTTP/1.1
//Content-Encoding: identity
//Content-Type: application/json; charset=UTF-8
//User-Agent: Resurface/2.2.1 (http_logger.js)
//Host: localhost:7701
//Connection: keep-alive
//Transfer-Encoding: chunked

//[["request_method","POST"],["response_code","200"],["now","1708555058014"],["host","MYPCNAME.local"]]

Parsing the given URL inside the HttpRequestImpl setter for the url field and setting protocol and hostname fields from there might help solve this issue.

Koa middleware

Support monitoring APIs built on Flask, using a middleware plugin similar to Express.

Use colon as separator in JSON keys

Using periods as separators in JSON keys makes parsing with regular expressions more difficult than it needs to be (since period is a special character and has to be escaped).

New format & log method signatures

Order params based on frequency of data:
request, response
request, response, response_body
request, response, response_body, request_body
request, response, response_body, request_body, now

SharedArrayBuffer is not supported on Electron

SharedArrayBuffer has not been supported for a while in all major browsers (unless the resource is cross-isolated).

Normally this is not an issue for back-end services and the corresponding middleware. However, for browser-based apps that use node as runtime environment -such as chromium-based electron- the SharedArrayBuffer variable is no longer available. This results in an error when trying to initialize a logger instance. As an example, see Kong/insomnia#5078

Content-Encoding header is not set properly from rule, only from options

Content-Encoding header is set to deflated instead of identity when skip_compression rule is present as part of options.rules but not options itself. This is not the expected result according to the logger API.

Expected behavior

let logger = new HttpLogger({url: 'http://localhost:7701/message', rules: 'include debug\n\nskip_compression'});
console.log(logger._url_options.headers);
//{
//  'Content-Encoding': 'identity',
//  'Content-Type': 'application/json; charset=UTF-8',
//  'User-Agent': 'Resurface/2.2.1 (http_logger.js)'
//}

Current behavior

let logger = new HttpLogger({url: 'http://localhost:7701/message', rules: 'include debug\n\nskip_compression'});
console.log(logger._url_options.headers);
//{
//  'Content-Encoding': 'deflate',
//  'Content-Type': 'application/json; charset=UTF-8',
//  'User-Agent': 'Resurface/2.2.1 (http_logger.js)'
//}

How to reproduce?

const { HttpLogger } = require('resurfaceio-logger');

let logger = new HttpLogger({url: 'http://localhost:7701/message', rules: 'include debug\n\nskip_compression'});

assert.equal(logger.skip_compression, true);
assert.equal(logger._url_options.headers['Content-Encoding'], 'identity');  // fails

The header can also be inspected with a packet capture tool like wireshark, or an HTTP proxy.

Code quality score is low

Our CodeFactor score is C+ due to a couple of code-formatting issues, which should be easy to resolve.

Invalid JSON logged with express-session middleware

Apparently express-session generates cookie headers that are string arrays, and these are not joined but passed along as JSON array elements, which leads to invalid JSON.

const session = require('express-session');
app.use(session({ secret: 'this-is-a-secret-token', cookie: { maxAge: 60000 }}));

Background submission with Axios

Send POST requests on a separate thread with bounded queue. Introduce BaseLogger.maxQueueDepth (with default value of 128) to control the depth of the bounded queue before the response is blocked.

BaseLogger.submit is where the handoff to the background thread should be done. (Rules engine and JSON conversion will continue to be done in the calling thread)

BaseLogger needs only a single background thread for performing POST requests since a single CPU core is normally capable of saturating the network.

Use async and axios libraries to do POST submissions asynchronously on a separate thread.

const async = require('async');
const transmitQ = async.queue((task, callback) => {
    send_message(task.message, callback);  // poll until queue is reasonably sized?
}, 1);
const axios = require('axios');
function send_message(message, callback) {
    try {
    axios.post(url, message.toString())
        .then(function (response) {
            if (response.status != 204) console.log("ARRRRHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
            callback();
        })
        .catch(function (error) {
            callback();
        });
    } catch (e) {
        callback();
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.