hapijs / good

hapi process monitoring
Other
525 stars 161 forks source link

Can't see any docs on how to add a custom stream #559

Closed ianbale closed 7 years ago

ianbale commented 7 years ago

I would like to know how to add a custom stream, but the docs are too vague and seem to expect previous knowledge that is not easy to identify. I'm fairly new to node.js, so apologies if I am asking about something that everyone else knows. I do not ask questions until I have exhausted every other avenue for finding the information that I need. In tis case, I have searched for just for about every search term that seems in any way relevant to what I want to achieve bit have come up empty handed.

All I want to do is customise an existing stream. I have take a copy of good-file/index.js and called it my-file.js and placed it in a folder /logger/

I have require my module and instantiated it:

const MyFileConstructor = require('./logger/my-file');
const MyFileLogger = new MyFileConstructor('./logs/api.txt')

Noe I need to add it to the options for Good:

reporters: {
        searchRequests: [{
            module: 'good-squeeze',
            name: 'Squeeze',
            args: [{
                response: ['api'],
                log: ['api'],
                error: ['api'],
            }]
        },{
            module : '**what goes here????? How do I reference my new logging module?**',
            args : ['./logs/api.txt'],
        }],
arb commented 7 years ago

Per the API documentation

module - can be :

  • a string that will be used to import a module from node_modules or a local file. Should export a single constructor function that can be invoked with new.
  • a function that is the constructor of your stream. It's a safer alternative to the string version when you risk having module conflicts.

So your case, it's probably a string to a local file. Additionally, if you just want to use good-file and have it log to "./logs/api.txt" you don't really need your own custom stream.

ianbale commented 7 years ago

Thank you,

I need to do some pretty complex logging, so will be extending it quite considerably later. Step one is just to get this simple example going.

I've removed

const MyFileConstructor = require('./logger/my-file');
const MyFileLogger = new MyFileConstructor('./logs/api.txt')

and change my module to

            module : appRootDir + '/logger/api',
            args : ['./logs/api.txt'],

But I am now seeing this error:

There was a problem (Error: Cannot pipe, not readable) in searchRequests and it has been destroyed.
Error: Cannot pipe, not readable
    at GoodFile.Writable.pipe (_stream_writable.js:188:22)
arb commented 7 years ago

What is being exported by appRootDir + '/logger/api'? Should either be a single function that is a constructor or an object with a constructor function attached to it.

ianbale commented 7 years ago

A copy of good-file with just the class name changed...

'use strict';

// Load modules

const Fs = require('fs-extra');

const internals = {
    defaults: {
        encoding: 'utf8',
        flags: 'a',
        mode: 0o666
    }
};

class Api extends Fs.WriteStream {
    constructor(path, options) {

        const settings = Object.assign({}, internals.defaults, options);
        settings.fd = -1; // prevent open from being called in `super`

        super(path, settings);
        this.open();
    }
    open() {

        this.fd = null;
        Fs.ensureFile(this.path, (err) => {

            if (err) {
                this.destroy();
                this.emit('error', err);
                return;
            }
            super.open();
        });
    }
}

module.exports = Api;
arb commented 7 years ago

Do console.dir(require(appRootDir + '/logger/api')) and see what is outputted.

ianbale commented 7 years ago

/Users/me/Source Code/my-app/logger/api

My module code is in /Users/me/Source Code/my-app/logger/api.js

arb commented 7 years ago

I am asking for console.dir(require(appRootDir + '/logger/api')) I want to see what is actually available at that path. You're going to have to start doing some debugging as I can't see your entire project. Most likely is that the module path you are passing is not correct and when good tries to create your stream it's trying to invoke undefined or something.

What version of node are you on as a side question?

ianbale commented 7 years ago

Sorry. Tired eyes last night... 18 hours straight working on this app! I did console.dir(appRootDir + '/logger/api') rather than what you asked for...

The output for the command you actually asked for is [Function: Api]

I'm using node v6.11.0

I would like to get to the bottom of this as I am sure I will want to use this elsewhere, but I have decided to use good-http to send the logs to a separate logging application rather than log from within the main app.

arb commented 7 years ago

Try putting some logging in these lines locally. Also, looking at the file you are trying to log too... that might not be a place node can write to so maybe use an absolute path as well, see if that makes any difference.

ianbale commented 7 years ago

Sorry for the very slow response. My son's having treatment for cancer and we've had a fair bit of time in hospital these past couple of weeks, so not been able to get back to this until now.

I did spent a little time on it though. I swapped my logger from something based on good-file to good-http and that just seemed to work. What I have now is a basis of a good-kafka module. Although right now, it's not self-contained, but instead uses an external "kafka logging" module in my project, plus it's dependent on kafka-node.

I'm not sure how easy it's going be to make it completely self contained (other than needing kafka-node), but I'll give it a go. If I sort it I will release it to npm.

Thanks for all your help.

lock[bot] commented 4 years ago

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.