Как регистрировать ошибки JS от клиента в кибане?
У меня есть конец веб-приложения в NodeJS и logstash/elasticsearch/kibana
для обработки системных журналов, таких как (access_error.log, messages.log etc)
.
Сейчас мне нужно также записывать все ошибки на стороне клиента JavaScript в kibana. Каков наилучший способ сделать это?
EDIT: Мне нужно добавить дополнительную информацию по этому вопросу. Поскольку @Jackie Xu обеспечивает частичное решение моей проблемы и как следует из моего комментария:
Меня больше всего интересует обработка ошибок на стороне сервера. Я думаю, что это не эффективная запись каждой ошибки в файл. Я ищу лучшие практики, чтобы повысить производительность.
Мне нужно обрабатывать записи ошибок js на стороне сервера более эффективно, чем просто записывать в файл. Можете ли вы предоставить некоторые сценарии, как я могу увеличить производительность ведения журнала на стороне сервера?
Ответы
Ответ 1
Когда вы говорите клиент, я предполагаю, что вы имеете в виду клиент регистрации, а не веб-клиент.
Во-первых, сделайте привычкой регистрировать свои ошибки в общем формате. Logstash любит согласованность, поэтому, если вы помещаете текст и JSON в один и тот же журнал вывода, вы столкнетесь с проблемами. Подсказка: войдите в JSON. Это потрясающе и невероятно гибко.
Общий процесс будет выглядеть следующим образом:
- Ошибка в вашем приложении.
- Запишите ошибку в файл, сокет или через сеть.
- Скажите logstash, как получить (ввести) эту ошибку (т.е. из файла, прослушать через сеть и т.д.)
- Сообщите logstash для отправки (вывода) ошибки в Elasticsearch (который может работать на одном компьютере)
В вашем приложении попробуйте использовать bunyan logger для node. https://github.com/trentm/node-bunyan
node app index.js
var bunyan = require('bunyan');
var log = bunyan.createLogger({
name: 'myapp',
streams: [{
level: 'info',
stream: process.stdout // log INFO and above to stdout
}, {
level: 'error',
path: '/var/log/myapp-error.log' // log ERROR and above to a file
}]
});
// Log stuff like this
log.info({status: 'started'}, 'foo bar message');
// Also, in express you can catch all errors like this
app.use(function(err, req, res, next) {
log.error(err);
res.send(500, 'An error occurred');
});
Затем вам нужно настроить logstash для чтения этих файлов журнала JSON и отправить Elasticsearch/Kibana. Сделайте файл с именем myapp.conf и попробуйте следующее:
logstash config myapp.conf
# Input can read from many places, but here we're just reading the app error log
input {
file {
type => "my-app"
path => [ "/var/log/myapp/*.log" ]
codec => "json"
}
}
# Output can go many places, here we send to elasticsearch (pick one below)
output {
elasticsearch {
# Do this if elasticsearch is running somewhere else
host => "your.elasticsearch.hostname"
# Do this if elasticsearch is running on the same machine
host => "localhost"
# Do this if you want to run an embedded elastic search in logstash
embedded => true
}
}
Затем запустите/перезапустите logstash как таковой: bin/logstash agent -f myapp.conf web
Перейдите в поиск elasticsearch на http://your-elasticsearch-host:9292
, чтобы увидеть входящие журналы.
Ответ 2
Сначала вам придется сначала поймать все ошибки на стороне клиента (и отправить их на ваш сервер):
window.onerror = function (message, url, lineNumber) {
// Send error to server for storage
yourAjaxImplementation('http://domain.com/error-logger/', {
lineNumber: lineNumber,
message: message,
url: url
})
// Allow default error handling, set to true to disable
return false
}
Впоследствии вы можете использовать NodeJS для записи этих сообщений об ошибках в журнал. Logstash может их собрать, а затем вы можете использовать Kibana для визуализации.
Обратите внимание, что в соответствии с Mozilla window.onerror не работает для каждой ошибки. Возможно, вам захочется переключиться на что-то вроде Sentry (если вы не хотите платить, вы можете напрямую получить источник из GitHub).
Ответ 3
Ошибки регистрации через встроенное ведение журнала по умолчанию позволяют сохранять ваши ошибки, а также позволяют вашему ядру оптимизировать записи для вас.
Если вы действительно думаете, что это недостаточно быстро (вы получаете много ошибок?), вы могли бы просто поместить их в redis.
Logstash имеет redis pub/sub input, поэтому вы можете хранить ошибки в redis, а logstash вытаскивает их и сохраняет их в вашем случае в elasticsearch.
Я предполагаю, что logstash/es находятся на другом сервере, иначе действительно нет смысла делать это, es также должен хранить данные на диске, и это не так эффективно, как запись файла журнала.
С любым решением, с которым вы работаете, вы хотите сохранить данные, например. записывая его на диск. Добавление только к одному (журнальному) файлу очень эффективно, и при сохранении данных единственный способ, которым вы можете обрабатывать больше, - это обмануть его на нескольких дисках/узлах.
Ответ 4
Если я правильно понимаю, проблема заключается в том, что вы не отправляете свои журналы на сервер (или @Jackie-xu предоставили некоторые подсказки), а скорее о том, как отправить их в elastiscsearch наиболее эффективно.
На самом деле подавляющее большинство пользователей классического стека Logstash/Elasticsearch/Kibana
используются для приложения, которое входит в файл, а затем используют плагин Logstash для чтения файлов для разбора этого файла и отправки результата в ElasticSearch. Поскольку @methai дал хорошее объяснение, я больше не буду этого делать.
Но я бы хотел, чтобы:
Вы не вынуждены использовать Logstash.
Фактически основная роль Logstash - собирать журналы, анализировать их, чтобы идентифицировать их структуру и повторяющееся поле, и, наконец, выводить их в формате JSON, чтобы их можно было отправить в ElasticSearch. Но поскольку вы уже манипулируете javascript на стороне клиента, можно легко представить, что вы будете говорить напрямую с сервером Elasticsearch.
Например, как только вы поймали исключение javascript, вы можете сделать следующее:
var xhr = new XMLHttpRequest();
xhr.open("PUT", http://your-elasticsearch-host:9292, true);
var data = {
lineNumber: lineNumber,
message: message,
url: url
}
xhr.send(JSON.stringify(data));
Выполняя это, вы напрямую разговариваете с клиентом на ElasticSearch Server. Я не могу представить себе более простой и быстрый способ сделать это (но обратите внимание, что это просто теория, я никогда не пробовал себя, поэтому реальность может быть более сложной, особенно если вы хотите, чтобы были созданы специальные поля, такие как отметки времени даты;)). В рабочем контексте вы, вероятно, будете иметь проблемы с безопасностью, возможно, прокси-сервер между клиентом и ES-сервером, но принцип существует.
Если вы абсолютно хотите использовать Logstash, вы не будете вынуждены использовать ввод файла
Если в целях согласования, делая то же самое, что и у всех, или для использования расширенного разбора синтаксического анализа логсташей, который вы хотите придерживаться в Logstash, вы должны взглянуть на все альтернативные входы для ввода основного файла. Например, я использовал сам канал, с процессом, ответственным за сбор журналов и вывод их на стандартный вывод. Существует также возможность читать на открытом tcp-сокете и многое другое, вы даже можете добавить свой собственный.