Как правильно разделить ведение журнала между запросами и ответами с помощью Morgan?

Документация Моргана описывает, что возможно разделить регистрацию запросов и ответов:

сплит / двойная регистрация

morgan Промежуточное программное обеспечение может использоваться столько раз, сколько необходимо, обеспечивая такие комбинации, как:

  • Запись в журнале по запросу и одна по ответу
  • Журнал все запросы в файл, но ошибки на консоль

В их единственном связанном примере есть некоторые комментарии, описывающие, что одно промежуточное программное обеспечение будет регистрировать ответы об ошибках в консоли, а другое - в файл:

// log only 4xx and 5xx responses to console
app.use(morgan('dev', {
  skip: function (req, res) { return res.statusCode < 400 }
}))

// log all requests to access.log
app.use(morgan('common', {
  stream: fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'})
}))

Который, кажется, достигает второго примера регистрации всех запросов к файлу и ошибок на консоли, но не первого.

Я немного растерялся, я не мог понять, что говорит morgan регистрировать только запрос или только ответы. Должен ли я заботиться о том, где правильно разместить эти промежуточные программы?

В настоящее время у меня есть одна запись журнала для запроса и ответа, я думаю:

morgan('[:date[clf]] :remote-addr :url :method HTTP/:http-version :status :remote-user :res[content-length] :referrer :user-agent :response-time ms', {
  stream: {
    write: (message) => {
      winston.silly(message.trim());
    }
  }
});

Итак, как я могу правильно регистрировать запросы в morgan вызов промежуточного программного обеспечения, а ответы в другом?

1 ответ

Решение

Мне удалось разделить протоколирование Моргана между запросами и ответами с помощью immediate опция:

немедленный

Напишите строку журнала по запросу вместо ответа. Это означает, что запросы будут регистрироваться даже в случае сбоя сервера, но данные из ответа (например, код ответа, длина содержимого и т. Д.) Не могут быть зарегистрированы.

Итак, вместо того, чтобы иметь эту смешанную регистрацию:

app.use(morgan(':remote-addr :url :method HTTP/:http-version :status :res[content-length] :user-agent :response-time ms', {
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

Можно разделить их и войти в их правильном порядке:

// Logs requests
app.use(morgan(':remote-addr :url :method HTTP/:http-version :user-agent', {
  // https://github.com/expressjs/morgan#immediate
  immediate: true,
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

// Logs responses
app.use(morgan(':remote-addr :url :method :status :res[content-length] :response-time ms', {
  stream: {
    write: (message) => {
      winston.info(message.trim());
    }
  }
}));

Примечание: поскольку express просто расширяет собственные объекты запросов и ответов Node, я считаю, что это внутренне res.on('finish', req => { /* log stuff */ }) когда он не установлен immediate,

Другие вопросы по тегам