Enable logs for SmartActions with morgan

Hello there :wave:

On our project, I’m currently working on the enhancement of our logs system, to provide more details about each requests. However, for some reason, the logger morgan is unable to log when an User use a SmartAction.

For reference, I’m following this documentation Track users’ logs with morgan - Woodshop.

Is there a way to enable log for SmartActions? I know about the Activity tab but we really would like to include the logs of the SmartActions directly within morgan.

Thanks!


p.s: On this code, I had to replace this line ip: tokens.ip(req, res), by ip: tokens['remote-addr'](req, res), in order to make it working properly

Hello @Danny,

When trying to do so, do you have any server side error?

Is it working the right way with other requests?

Kind regards,
Louis

I have no errors in the console or network tab of the browser. For the CLI, no errors as well, let me show you what I got in the CLI:

This is what I got when I confirm my SmartAction. As you can see, I can only see the GET request, not the POST that trigger the SmartAction, or the PATCH behind the SmartAction.

And there is the code related to morgan in my app.js

const morgan = require('morgan');

morgan.token('user', (req) => {
    if (req.user) { return req.user.email; }
    return 'no user info';
});
morgan.token('team', (req) => {
    if (req.user) { return req.user.team; }
    return '-';
});

function jsonFormat(tokens, req, res) {
    return JSON.stringify({
        ip: tokens['remote-addr'](req, res),
        user: tokens.user(req, res),
        team: tokens.team(req, res),
        time: tokens.date(req, res, 'iso'),
        method: tokens.method(req, res),
        url: tokens.url(req, res),
        'http-version': tokens['http-version'](req, res),
        'status-code': tokens.status(req, res),
        'content-length': tokens.res(req, res, 'content-length'),
        referrer: tokens.referrer(req, res),
        'user-agent': tokens['user-agent'](req, res),
        'response-time': tokens['response-time'](req, res) + ' ms',
        params: res.req.params,
        body: res.req.body,
        query: res.req.query
    });
}

app.use(morgan(jsonFormat));

Thanks for your time!

I check on my project, i also using morgan and indeed the smart-action request are not logged

Where did you execute the following line?

app.use(morgan(jsonFormat));

Can you try to move the call just after const app = express()?

It is not just after but definitely after :slight_smile:


const morgan = require('morgan');

const app = express();

// ...

app.use(errorHandler());

// Create custom logs with morgan
morgan.token('user', (req) => {
    if (req.user) { return req.user.email; }
    return 'no user info';
});
morgan.token('team', (req) => {
    if (req.user) { return req.user.team; }
    return 'none';
});

function jsonFormat(tokens, req, res) {
    return JSON.stringify({
        ip: tokens['remote-addr'](req, res),
        user: tokens.user(req, res),
        team: tokens.team(req, res),
        time: tokens.date(req, res, 'iso'),
        method: tokens.method(req, res),
        url: tokens.url(req, res),
        'http-version': tokens['http-version'](req, res),
        'status-code': tokens.status(req, res),
        'content-length': tokens.res(req, res, 'content-length'),
        referrer: tokens.referrer(req, res),
        'user-agent': tokens['user-agent'](req, res),
        'response-time': tokens['response-time'](req, res) + ' ms',
        params: res.req.params,
        body: res.req.body,
        query: res.req.query
    });
}

app.use(morgan(jsonFormat));

module.exports = app;

@Danny @Justin_Martin

Hello everyone :wave:

After playing with the Morgan logger, I have figure out something.

Please, be sure to initialise Morgan (eg call app.use(morgan(jsonFormat));) right after the line configuring the jwt middleware, and before the lines that initialise your forest routes.

In a generated project from the forest-cli, it should look like something like this:

...
app.use(jwt({
  secret: process.env.FOREST_AUTH_SECRET,
  credentialsRequired: false,
  algorithms: ['HS256'],
}));

<==Put the morgan configuration and middleware right here !==>

app.use('/forest', (request, response, next) => {
  if (PUBLIC_ROUTES.includes(request.url)) {
    return next();
  }
  return ensureAuthenticated(request, response, next);
});

requireAll({
  dirname: path.join(__dirname, 'routes'),
  recursive: true,
  resolve: (Module) => app.use('/forest', Module),
});

requireAll({
  dirname: path.join(__dirname, 'middlewares'),
  recursive: true,
  resolve: (Module) => Module(app),
});

...

Now, we ensure that Morgan logging system will be called before the route is even handled by any code.

Keep in mind that you absolutely need to initialise Morgan after the jwt library, otherwise you will not be able to retrieve any information from the user, as the jwt library is responsible for filling in the request.user attribute.

I hope this can help !

Steve.

5 Likes

Can you update this documentation file to ensure others dev will not face the same issue
https://docs.forestadmin.com/woodshop/how-tos/get-user-specific-activity-from-your-server-logs