2016-10-04 2 views
7

Я работаю над API, который совершает много вызовов, некоторые из них должны быть тщательно зарегистрированы по различным причинам.Будет ли регистрировать запрос индивидуально хорошей практики или беспорядка?

На данный момент я регистрирую все операции ввода/вывода/обработки в функции, и API работает безупречно, поэтому нет необходимости увеличивать количество протоколирования.

Но идея, которая поцарапала мои мысли, - присвоить UUID каждому входящему API-вызову, который будет следовать за регистрацией во внутренних функциях.

Хотя это создавало бы достаточное количество дополнительных параметров, чтобы следовать UUID в каждой функции, мне интересно, является ли это обычной практикой, и если я должен реализовать ее до возникновения проблемы, и в то время как количество изменений, которые нужно сделать является управляемым.

Ex:

Очевидно, что реальный код является гораздо более сложным, и не использует console.log для входа

const express = require('express'), 
    fs = require('fs'), 
    config = require('./config.json'), 
    app = express(); 

function foo(bar, callback) { 
    console.log(bar); 
    fs.open(bar, (err, data) => { 
     if(err) { 
      console.err(err); 
      callback(err); 
     } else { 
      console.log(data) 
      callback(null, data); 
     } 
    }); 
} 

app.get('/foo', (req, res) => { 
    console.log(req.body); 
    foo(req.body.bar, (err, result) => { 
     if(err) { 
      console.err(err); 
      res.send(err); 
     } else { 
      console.log(result) 
      res.send(null, result); 
     } 
    }); 
}); 

app.listen(config.port); 

To:

const express = require('express'), 
    UUID = require('uuid-generator'), 
    fs = require('fs'), 
    config = require('./config.json'), 
    app = express(); 

function foo(uuid, bar, callback) { 
    console.log(uuid + ': ' + bar); 
    fs.open(bar, (err, data) => { 
     if(err) { 
      console.err(uuid + ': ' + err); 
      callback(err); 
     } else { 
      console.log(uuid + ': ' + data) 
      callback(null, data); 
     } 
    }); 
} 

app.use((req, res, next) => { 
    req.id = new UUID(); 
    next(); 
}); 

app.get('/foo', (req, res) => { 
    console.log(req.id + ': ' + req.body); 
    foo(req.id, req.body.bar, (err, result) => { 
     if(err) { 
      console.err(req.id + ': ' + err); 
      res.send(err); 
     } else { 
      console.log(req.id + ': ' + result) 
      res.send(null, result); 
     } 
    }); 
}); 

app.listen(config.port); 

Про бы, что , в случае сбоя функции или в случае сбоя системы, мы могли бы точно определить, какой вызов вызвал ошибку, и какой путь он следит d более легко.

Кон, это требует незначительного объема работы для реализации, и может быть, это не так полезно, поскольку мы уже можем определить путь, следующий за различными входными/выходными данными и другими уже выполненными протоколами.

TL: DR: Обычная практика заключается в том,

Есть ли инструменты, которые автоматизируют это, и я не должен заботиться об этом в коде?

ответ

1

Я не могу прокомментировать, является ли это обычной практикой в ​​целом, но это была довольно распространенная практика для продуктов, над которыми я работал недавно.

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

Например, если у вас есть API, который принимает входные данные, которые необходимо сохранить, это может быть очень полезно для корреляции конкретных входных данных с неудачной записью базы данных.

Если вы решили добавить UUID к вашим запросам, то промежуточное ПО express-request-id является полезным модулем, который генерирует UUID для вас и добавит его в заголовки ответов. Он также может принимать UUID, если он присутствует в заголовке входящего запроса, и использовать его вместо этого, что полезно для отслеживания запросов между службами.

Я ничего не видел для узла, который будет абстрактно записывать отдельные запросы полностью, но я не искал этого.

0

Это хорошая практика для регистрации запросов, но не для stdout/stderr или файла. Лучший способ - отправить его на что-то вроде Logz.io или собственный экземпляр Logstash (может быть установлен на том же или другом компьютере) через TCP-сокет. Logstash должен быть подключен к управляемой службе AWS Elasticsearch или к той, которая установлена ​​локально или на удаленной машине. Если количество бревен не большое это может быть собранно очень быстро с помощью докер-Compose (для высоких пропускной способности я рекомендую посвященный находчивый сервер)

ELK Стека является удивительным набором инструментов для мониторинга, бревенчатые агрегации, Advansed запросов, чтобы найти конкретный запрос и сведения об этом, хотя тысячи тысяч записей в журнале. Это поисковая база данных nosql, которая уже почти стала одним из самых передовых в отрасли средств агрегирования журналов.

Logstash регистрирует журналы через различные протоколы, отправляет их в NoSQL Elasticsearch, а затем вы можете просматривать, создавать информационные панели и суммировать данные журнала с помощью внешнего интерфейса Kibana.

Существует причина для добавления заголовка X-Request-Id, как уже было предложено, и других метаданных инфраструктуры для ваших журналов и метрик времени.

Вот проект, который позволит вам настроить весь ELK набор инструментов на локальном компьютере https://github.com/deviantony/docker-elk

Logging может быть сделано с помощью: - https://www.npmjs.com/package/winston (с использованием https://www.npmjs.com/package/winston-logstash) - https://www.npmjs.com/package/bunyanhttps://www.npmjs.com/package/bunyan-logstash)

В обеих библиотеках имеется множество плагинов для других видов каротажа

+0

Я хочу следовать запросу внутри сервера, и звонки были сделаны для ответа на него. Мне не нужно следить за ним между разными серверами. Кроме того, ведение журнала уже отправлено на сервер, я использовал 'console.log', чтобы не показывать код, соединяющий и настраивающий формат журнала. – DrakaSAN

+1

вы можете попробовать: многозадачная асинхронная библиотека регистрации для node.js http://github.com/winstonjs/winston – Remario

+0

Вы можете использовать какой-то модуль для ведения журнала - например, 'winston' - у них много плагинов которые поддерживают очень разные транспорты и предназначены исключительно для этого puprose - для настройки ведения журнала, для регистрации uncaughtExceptions, для создания правильных журналов доступа (что вам нужно). ELK может быть локальным - просто в соответствии с тем, что вам требуется в вашем OP - это идеальное совпадение. Локально ELK можно было установить очень простым способом - с помощью компоновки докеров. – BlackStork

0
  1. Вы изучали morgan. Это промежуточное программное обеспечение для регистрации каждого запроса в файле, db и т. Д. Возможно, вы даже можете вывести журналы в logstash.

  2. Теперь, вместо передачи UUID каждой функции в виде отдельного аргумента, передайте ее в существующие данные json, передаваемые каждой функции.

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

Надеюсь, это поможет.

+0

Проблема в том, что я не буду передавать полный запрос каждой функции, потому что это нарушит читаемость, что я хочу чистый способ доступа к этому идентификатору из каждой функции без необходимости передавать его явно и загромождать мой код. Морган кажется хорошим, но не решает всей проблемы. – DrakaSAN

+0

@DrakaSAN Привет, я не говорю, чтобы передать объект req каждой функции для вызова, для разговора просто передайте uuid как дополнительное значение в текущем json, переданном функции в качестве аргумента. – KlwntSingh

+0

@DrakaSAN Если в java нужно сделать то же самое, мы используем локальный кеш потока, в котором выполняется текущий запрос. мы достигли того же самого в приложении узла, над которым я сейчас работаю. – KlwntSingh

Смежные вопросы