Woodshop for old agent generation
Try the new agent generation
  • What is woodshop
  • How to's
    • Smart Relationship
      • GetIdsFromRequest
    • Smart views
      • Display a calendar view
      • Create a custom tinder-like validation view
      • Create a custom moderation view
      • Create a dynamic calendar view for an event-booking use case
    • Configure environment variables
      • NodeJS/Express projects
    • Elasticsearch Integration
      • Interact with your Elasticsearch data
      • Elasticsearch service/utils
      • Another example
    • Zendesk Integration
      • Authentication, Filtering & Sorting
      • Display Zendesk tickets
      • Display Zendesk users
      • View tickets related to a user
      • Bonus: Direct link to Zendesk + change priority of a ticket
    • Dwolla integration
      • Display Dwolla customers
      • Display Dwolla funding sources
      • Display Dwolla transfers
      • Link users and Dwolla customers
      • Dwolla service
    • Make filters case insensitive
    • Use Azure Table Storage
    • Create multiple line charts
    • Create Charts with AWS Redshift
    • View soft-deleted records
    • Send Smart Action notifications to Slack
    • Authenticate a Forest Admin API against an OAuth protected API Backend
    • Translate your project into TypeScript
      • V8
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v7
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v6
    • Geocode an address with Algolia
    • Display/edit a nested document
    • Send an SMS with Zapier
    • Hash a password with bcrypt
    • Display a customized response
    • Search on a smart field with two joints
    • Override the count route
    • Make a field readOnly with Sequelize
    • Hubspot integration
      • Create a Hubspot company
      • Display Hubspot companies
    • Impersonate a user
    • Import data from a CSV file
    • Import data from a JSON file
    • Load smart fields using hook
    • Pre-fill a form with data from a relationship
    • Re-use a smart field logic
    • Link to record info in a smart view
    • Display data in html format
    • Upload files to AWS S3
    • Display AWS S3 files from signed URLs
    • Prevent record update
    • Display, search and update attributes from a JSON field
    • Add many existing records at the same time (hasMany-belongsTo relationship)
    • Track users’ logs with morgan
    • Search on relationship fields by default
    • Export related data as CSV
    • Run automated tests
  • Forest Admin Documentation
Powered by GitBook
On this page
  • Add new information
  • Customize the format of the logs
  • Store logs via a stream

Was this helpful?

  1. How to's

Track users’ logs with morgan

PreviousAdd many existing records at the same time (hasMany-belongsTo relationship)NextSearch on relationship fields by default

Last updated 4 years ago

Was this helpful?

Morgan is a logging middleware used to handle the logging of your admin backend. It is called this way in your app.js file:

app.js
const morgan = require('morgan')
...
app.use(morgan('tiny'))
...

The logs are printed in this format:

Screenshot 2020-07-21 at 18.17.25.png

This can be especially useful if you store your logs and use them to track user activities.

Add new information

You could add in your logging data like:

  • user IP (IP of the request),

  • user name & team from the Forest Admin token

You can adjust the code in your app.js file using the snippet below.

The logs printed will include information about the user IP, the user connected with Forest and his team.

app.js
const morgan = require('morgan')
...
morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
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 '-';
});

app.use(morgan(':ip :user :team [:date[clf]] :method :url :response-time'));
...

This will give you the following log output:

Customize the format of the logs

You can also use a custom format like a JSON to output your logs.

app.js
const morgan = require('morgan')
...

morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
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.ip(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),
  });
}

app.use(morgan(jsonFormat));
...

This will give you the following log output:

Store logs via a stream

You can also choose to store your logs using a stream. The following example shows how you can store your logs into a CSV file.

app.js
const morgan = require('morgan')
...

morgan.token('ip', (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress);
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 '-';
});

let accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.csv'), { flags: 'a' });

app.use(morgan(':ip,:user,:team,[:date[clf]],:method,:url,:response-time', { stream: accessLogStream }));
...

You can choose to have more verbose logs, add new information, and customize the log format using .

You can take a look at the package documentation .

Screenshot 2020-07-21 at 18.17.45.png
Screenshot 2020-07-21 at 17.58.38.png
morgan
here