Os logs do aplicativo revelam informações sobre eventos externos e internos que o aplicativo vê durante a execução. Quando um bug, hack ou anomalia ocorre durante uma implantação, os logs são a evidência mais útil e confiável para analisar as causas do incidente.
Vamos dar uma olhada em como escrever mensagens úteis no diário que todos vão adorar.
1. O que registrar
Mensagens de entrada e saída
Se os componentes interagem entre si usando mensagens, você precisa registrar as mensagens de entrada e saída, indicando os URLs dos endpoints da API, parâmetros de solicitação, solicitações de IP iniciais e intermediárias, cabeçalhos de solicitação, informações sobre o autor, corpos de solicitação e resposta, contexto de negócios , carimbos de data / hora e etapas de processamento interno.
É muito importante que cada mensagem receba um identificador exclusivo (geralmente gerado no gerenciador de API ou nível de serviço). Isso é necessário para rastrear a troca de mensagens entre os serviços do sistema.
Serviços e funções de chamada
Ao chamar um serviço ou função, é desejável registrar seu contexto com mais detalhes, principalmente para depuração (use TRACE ou DEBUG). Esses logs irão ajudá-lo a solucionar problemas de lógica de negócios, especialmente se você não tiver o privilégio de anexar um depurador a um aplicativo (por exemplo, ao implantar em um ambiente de teste, teste ou pré-produção).
Ações do usuário e estatísticas de negócios
Cada aplicativo possui cenários de negócios exclusivos e jornadas do usuário que fornecem muitas informações para profissionais especializados. Por exemplo, se uma determinada transação está demorando muito ou se os usuários estão presos a alguma funcionalidade - tudo isso são dados muito importantes do ponto de vista da experiência do usuário. Outras informações relacionadas ao negócio - o número de transações e usuários ativos, bem como suas etapas - são importantes para encontrar relações causais, podendo até ser utilizadas em análises de negócios.
Operações de dados (trilha de auditoria)
Por razões de segurança e regulamentares, a maioria dos aplicativos corporativos exige logs de transações separados com todas as informações importantes, como IDs de acesso (usuários e sistemas), instâncias de serviço exatas e privilégios de função usados, carimbos de data / hora, solicitações de dados, instantâneos e o novo estado dos dados alterados (diff). A trilha de auditoria deve registrar todas as operações com dados (acessar, importar, exportar, etc.), bem como as operações CRUD (criar, ler, atualizar, excluir) realizadas pelos usuários, outros sistemas e serviços.
Eventos do sistema
Isso inclui informações sobre o comportamento (inicia, pára, reinicia e eventos relacionados à segurança), modos transitórios (frio, aquecimento, quente), comunicação entre serviços (handshake, status de estabelecimento de conexão - conectado, desconectado, reconectado, novas tentativas), identificadores instâncias de serviço, servindo ativamente APIs, ouvindo ativamente em intervalos de portas e IP, configurações carregadas (bootstrap e atualizações dinâmicas), estado geral do serviço e qualquer outra coisa que possa ajudá-lo a entender o comportamento do sistema.
Estatísticas de desempenho
Diligência é uma grande característica dos dispositivos de computação, mas eles podem não funcionar perfeitamente. A qualquer momento, pode haver problemas de desempenho ou degradações inesperadas no serviço (principalmente devido a erros não tratados e dados corrompidos). Para determiná-los, é sempre recomendável publicar estatísticas sobre o funcionamento geral e o desempenho do sistema. Ele pode conter informações como contadores de chamadas de API (bem ou malsucedidas), latência de rede, duração média da viagem de ida e volta, consumo de memória e outras informações específicas do aplicativo (geralmente determinadas pelo contexto de negócios).
Ameaças e vulnerabilidades
Divulgar ameaças e vulnerabilidades com aplicativos de tempo de execução e logs é uma arte que qualquer desenvolvedor de software corporativo deve dominar. Hacks e glitches geralmente não acontecem de repente. Na maioria das vezes, há sinais de que ninguém percebe a princípio. Portanto, você deve sempre registrar atividades humanas suspeitas (por exemplo, tentativas erradas de autenticação e verificação com a aplicação de todas as informações de baixo nível, como redes usadas, fontes de solicitações, funções de usuário e privilégios), bem como o comportamento do sistema (por exemplo, um aumento nos picos nos padrões de consumo de recursos, alta carga em servidores web, falhas ocasionais de serviço). Ao notar um evento suspeito, certifique-se de que os logs contenham todas as informações relacionadas a ele. Perfeitamente,para que seja um rastreamento de pilha completo com valores de parâmetro e informações adicionais obtidas do contexto do aplicativo.
2. O que você não precisa registrar
Informação pessoal
Quase todas as leis de privacidade (por exemplo, GDPR, CCPA) recomendam explicitamente que os desenvolvedores não registrem informações de identificação pessoal. Isso inclui nome, apelidos, sexo, aniversário, endereço, e-mail, números de telefone, número do seguro social e números de cartão de crédito.
Nomes de empresas e informações de contato
Certifique-se de não anotar nomes de empresas, informações de funcionários, clientes, fornecedores ou empresas e informações de contato individuais. O jornal nunca deve divulgar relações comerciais e transações com terceiros. Para rastrear transações específicas, use IDs de eventos gerados pelo sistema em vez de nomes reais e passe-os para outros serviços.
Dados financeiros (contas bancárias, detalhes de cartões bancários, valores enviados, etc.)
Por lei, todos os dados financeiros devem ser completamente removidos ou mascarados. A divulgação de tais informações em revistas pode facilmente levar a ações judiciais sérias (incluindo responsabilidade criminal). Evite isso por todos os meios.
Senhas, chaves e segredos de segurança, tokens de autenticação
Credenciais e tokens de autenticação são considerados informações confidenciais, portanto, sua presença nos logs ajudará os invasores a encontrar facilmente falhas no sistema. Portanto, não deixe esses dados entrarem nos logs.
Nota: Você pode determinar facilmente quais informações ocultar dos logs se adicionar um atributo a cada campo que determina o nível de visibilidade (por exemplo, mostrar, mascarar, ocultar, criptografar). Se você tiver esse mecanismo, poderá alterar a visibilidade dos campos simplesmente atualizando as propriedades na configuração. Esta é uma boa solução nos casos em que você precisa registrar algumas informações do usuário em ambientes que não sejam de combate, especialmente para teste e depuração. Ou você pode escrever analisadores que filtram logs e processam campos confidenciais de acordo com instruções pré-escritas para o ambiente.
3. Melhores práticas
Saiba quando usar um determinado nível de registro
O nível de registro é usado para indicar a gravidade de cada elemento do sistema. A maioria das estruturas de registro tem estes níveis:
- FATAL : erros muito sérios que provavelmente farão com que o aplicativo seja encerrado. Isso geralmente termina com falhas graves.
- ERROR : erros com os quais o aplicativo ainda pode continuar a funcionar, mas com a deterioração de certas capacidades.
- WARN : eventos menos perigosos em comparação com erros. Eles geralmente não degradam ou travam o aplicativo completamente. Mas esses ainda são eventos importantes que precisam ser investigados.
- INFO : banners de eventos importantes e mensagens informativas no comportamento do aplicativo.
- DEBUG: , . .
- TRACE: , , . .
O Linux Syslog também tem níveis mais sérios, como Emergência, Alerta, Crítico, Erro, Aviso, Aviso, Informativo e Depuração.
Independentemente da complexidade e profundidade de cada nível de registro, devemos configurá-los corretamente em nosso código para fornecer a quantidade ideal de informações em cada cenário. Por exemplo, todos os dados usados pelos desenvolvedores para depuração e análise técnica devem ir nos níveis DEBUG ou TRACE, e os banners com dados do sistema devem ir abaixo de INFO.
Use inglês
Algumas ferramentas e consoles não oferecem suporte à saída e armazenamento de logs com determinados caracteres Unicode. Portanto, a localização e outras melhorias podem ser difíceis. Limite-se ao inglês e sempre use um conjunto de caracteres amplamente aceito para escrever mensagens.
2020-11-11 13:52:18 DEBUG App:36 - Loading adapters.. 2020-11-11 13:52:21 DEBUG Adapters:10 - Loading adapter docs/v1 2020-11-11 13:52:22 DEBUG Adapters:16 - Loading adapter mongo/v1 2020-11-11 13:52:26 DEBUG Docs:38 - docs adapter initialized 2020-11-11 13:52:27 DEBUG Mongo:38 - mongo adapter initialized 2020-11-11 13:52:22 DEBUG Adapters:20 - Successfully loaded all
Adicione mensagens amigáveis ao desenvolvedor (concisas e significativas)
Se houver pouco registro, não poderemos obter as informações de que precisamos para recriar o contexto de cada evento importante. E se você registrar muito, isso degradará o desempenho: gravar um arquivo de log enorme aumentará o consumo de recursos de E / S e armazenamento em disco. Se o sistema de arquivos não oferecer suporte, reduzirá o desempenho geral do sistema.
Para otimizar as mensagens, você precisa de um entendimento claro das expectativas funcionais e não funcionais do sistema e do planejamento da qualidade e quantidade de mensagens desejadas. Cada diário deve ser significativo e apropriado ao contexto: sempre escreva brevemente e direto ao ponto.
2020-11-11 13:52:27 DEBUG Users:18 - Successfully created new user (RecordID: 5f5a0d594d17e22b848ee570)2020-11-11 13:52:27 ERROR Users:34 - Failed to update DB (E: inactive user, RecordID: 5f5a0d594d17e22b848ee570)
Crie identificadores de referência, aliases e modelos simplificados para mensagens longas e frequentemente usadas
Em vez de escrever uma descrição completa a cada vez, tente criar identificadores de referência ou modelos simplificados para representar descrições longas e repetitivas no log. Isso reduz o número total e o comprimento das mensagens e também aumenta a flexibilidade para ocultar certas informações. Por exemplo, em vez de descrever uma vulnerabilidade em um log de texto, é melhor usar um alias ou identificador para que apenas especialistas especializados possam entender o cenário atual.
2020-11-11 13:52:27 ERROR DB:22 - Failed to write (E:ORA-01017)// ORA-01017 denotes "invalid username/password; logon denied" error message
Use timestamps corretos
Os carimbos de data / hora fornecem informações sobre a sequência de eventos e são essenciais para depuração e análise. Ao fixar o tempo, é recomendado usar os valores mais detalhados (por exemplo, no nível de milissegundos ou microssegundos) para que seja mais fácil identificar eventos adjacentes. Além disso, verifique se os carimbos de data / hora estão no início da mensagem no formato aaaa-mm-dd HH: mm: ss. Sempre especifique seu fuso horário, a menos que esteja usando o horário padrão do servidor (UTC).
// with default server time (UTC)2020-11-11 13:52:12 INFO XYZ Integration API Manager v2.0.0// with timezone (e.g. PST - Pacific Standard Time)2020-11-11 13:52:12PST INFO XYZ Integration API Manager v2.0.0
Fornece a fonte ou origem dos dados de registro (para DEBUG, TRACE, ERROR)
Isso é muito útil para identificar claramente o local que levou à mensagem correspondente. Algumas estruturas de registro permitem que você especifique fontes no nível mais detalhado (até o nome dos arquivos com números de linha), mas na maioria das vezes, mencionar apenas a classe, função ou nome do arquivo é suficiente.
2020-11-11 13:52:12 INFO app - XYZ Integration API Manager v2.0.0 2020-11-11 13:52:15 INFO app - Loading configurations.. 2020-11-11 13:52:18 INFO app - *** InstanceID APIM_V2_I02 2020-11-11 13:52:18 INFO app — *** BaseURL http://10.244.2.168:3000 2020-11-11 13:52:19 INFO app - *** LogLevel 05 (DEBUG) 2020-11-11 13:52:12 DEBUG App:22 - Initializing Swagger UI.. 2020-11-11 13:52:14 DEBUG App:28 - Generating schemata.. 2020-11-11 13:52:14 DEBUG App:30 - Initializing REST services.. 2020-11-11 13:52:15 DEBUG App:32 - Generating documentation.. 2020-11-11 13:52:18 DEBUG App:36 - Loading adapters.. 2020-11-11 13:52:21 DEBUG Adapters:10 - Loading adapter docs/v1 2020-11-11 13:52:22 DEBUG Adapters:16 - Loading adapter mongo/v1 2020-11-11 13:52:26 DEBUG Docs:38 - docs adapter initialized 2020-11-11 13:52:27 DEBUG Mongo:38 - mongo adapter initialized 2020-11-11 13:52:22 DEBUG Adapters:20 - Successfully loaded all 2020-11-11 13:52:31 INFO app - Started listening...
Cada jornal deve ser único dentro do sistema
A maioria dos novatos comete o mesmo erro - eles copiam e colam uma mensagem de amostra em arquivos diferentes, coletando o registro final das mesmas linhas provenientes de diferentes partes do sistema. Nesse caso, é difícil rastrear o local específico que disparou o evento. Se o conjunto de palavras não puder ser alterado, pelo menos mencione a fonte na mensagem para que as linhas no arquivo final sejam diferentes umas das outras. Além disso, se o registro for manipulado pela classe pai, envie um identificador na inicialização e use-o para registrar mensagens sobre o comportamento das classes filho.
2020-11-11 13:52:18 DEBUG App:36 - Loading adapters.. 2020-11-11 13:52:21 DEBUG Adapters:10 - Loading adapter docs/v1 2020-11-11 13:52:22 DEBUG Adapters:16 - Loading adapter mongo/v1 2020-11-11 13:52:26 DEBUG Docs:38 - docs adapter initialized 2020-11-11 13:52:27 DEBUG Mongo:38 - mongo adapter initialized 2020-11-11 13:52:22 DEBUG Adapters:20 - Successfully loaded all
Adicionar um ID rastreado ou token de mensagem à mensagem
Quando um evento ou mensagem entra no sistema, geralmente é atribuído um identificador exclusivo. Ele pode ser passado para outros estágios de processamento para rastrear o movimento de um evento pelo sistema, o que é útil para depuração, processamento simultâneo e operações orientadas a dados. Idealmente, o sistema deve ter um identificador de evento exclusivo em todos os módulos e serviços.
[87d4s-a98d7-9a8742jsd] Request Body: { "request_id": "87d4s-a98d7-9a8742jsd", "app_id": "TX001", "option_val": "IBM", "req_type_id": "0013", "data": {...........} [87d4s-a98d7-9a8742jsd] Sending request to RefData: href="http://10.244.2.168:8280/v1
Identificadores de correspondência em pontos de transição
Em certos casos, principalmente na transmissão de um evento de um sistema para outro, os identificadores mudam de acordo com a convenção adotada no outro sistema. Em tais pontos de transição, é necessário indicar explicitamente a correspondência dos identificadores antigos e novos em uma mensagem separada, com a adição do contexto necessário.
[1000508] ***** Incoming request from 10.244.2.168:3000 ***** [1000508] Origin Id: 87d4s-a98d7-9a8742jsd -> System ID: 1000508 [1000508] Transaction successfully added to Rabbit Queue
Especifique identificadores para todas as instâncias de serviço
A maioria dos sistemas corporativos são plataformas de computação distribuídas nas quais existem muitas instâncias dos mesmos serviços com várias configurações de aplicativos, recursos, versões e propriedades de rede. É recomendável atribuir identificadores às instâncias e usá-los para comunicação entre serviços.
2020-11-11 13:52:12 INFO app - XYZ Integration API Manager v2.0.0 2020-11-11 13:52:15 INFO app - Loading configurations.. 2020-11-11 13:52:18 INFO app - *** InstanceID APIM_V2_I02 2020-11-11 13:52:18 INFO app — *** BaseURL http://10.244.2.168:3000 2020-11-11 13:52:19 INFO app - *** LogLevel 05 (DEBUG)
Configure um nível de registro ativo
O nível de log ativo deve ser alterado dependendo do ambiente de implementação. Para produção, é recomendado gerar logs de saída até o nível INFO. Em outros ambientes, os logs são produzidos até o nível DEBUG ou TRACE, dependendo do nível de detalhe exigido pelas equipes de desenvolvimento e manutenção.
// Active Log Level = DEBUG2020-11-11 13:52:12 INFO app - XYZ Integration API Manager v2.0.0 2020-11-11 13:52:15 INFO app - Loading configurations.. 2020-11-11 13:52:18 INFO app - *** InstanceID APIM_V2_I02 2020-11-11 13:52:18 INFO app — *** BaseURL http://10.244.2.168:3000 2020-11-11 13:52:19 INFO app - *** LogLevel 05 (DEBUG) 2020-11-11 13:52:12 DEBUG App:22 - Initializing Swagger UI.. 2020-11-11 13:52:14 DEBUG App:28 - Generating schemata.. 2020-11-11 13:52:14 DEBUG App:30 - Initializing REST services.. 2020-11-11 13:52:15 DEBUG App:32 - Generating documentation.. 2020-11-11 13:52:18 DEBUG App:36 - Loading adapters.. 2020-11-11 13:52:21 DEBUG Adapters:10 - Loading adapter docs/v1 2020-11-11 13:52:22 DEBUG Adapters:16 - Loading adapter mongo/v1 2020-11-11 13:52:26 DEBUG Docs:38 - docs adapter initialized 2020-11-11 13:52:27 DEBUG Mongo:38 - mongo adapter initialized 2020-11-11 13:52:22 DEBUG Adapters:20 - Successfully loaded all 2020-11-11 13:52:31 INFO app - Started listening...// Active Log Level = INFO2020-11-11 13:52:12 INFO app - XYZ Integration API Manager v2.0.0 2020-11-11 13:52:15 INFO app - Loading configurations.. 2020-11-11 13:52:18 INFO app - *** InstanceID API_V2_I02 2020-11-11 13:52:18 INFO app — *** BaseURL http://10.244.2.168:3000 2020-11-11 13:52:19 INFO app - *** LogLevel 04 (INFO) 2020-11-11 13:52:31 INFO app - Started listening...
Fornece contexto suficiente para erros e falhas
Erros e falhas requerem uma investigação mais completa. Para fazer isso, o aplicativo deve fornecer aos especialistas no assunto as informações de que precisam, bem como a tecnologia e o contexto de negócios. Por exemplo, se uma solicitação ou mensagem não puder ser processada, é muito útil registrar o corpo da solicitação com falha, além do erro.
[1000508] ***** Incoming request from 10.244.2.168:3000 *****[1000508] Origin Id: 87d4s-a98d7-9a8742jsd -> System ID: 1000508[1000508] Failed to validate msg body (E: Uncaught ReferenceError: missing params - option_val)[1000508] Failed Message: { "request_id": "87d4s-a98d7-9a8742jsd", "app_id": "TX001", "req_type_id": "0013", "data": {...........} }
Faça backup das transações de dados com evidências (não suponha!)
Para cada operação de dados, não tome como certo que ela foi bem-sucedida. Sempre verifique a condição final com evidências. Por exemplo, quando você cria, atualiza ou exclui um registro no banco de dados, ele retorna um contador dos registros alterados e o próprio registro atualizado. Sempre verifique o contador ou resultado esperado. Outro exemplo: ao inserir um registro em uma estrutura de dados (por exemplo, em uma fila), verifique se seu tamanho aumentou. Suponha que seu sistema use operações simultâneas, mas a fila não as suporta. Então, você pode perder alguns registros e a única maneira de detectar esses erros ocultos no código é verificar o comprimento.
DEBUG BatchWriter:28 - Successfully connected to DB. Trying to insert 24 accounts...DEBUG BatchWriter:35 - Successfully inserted 24 accounts. Total DB rows affected: 24
Criptografar ou mascarar dados confidenciais
Normalmente, a lei exige que as informações confidenciais de usuários e sistemas internos sejam mascaradas e / ou criptografadas. Os requisitos regulamentares podem variar dependendo do seu setor e local de trabalho. Descubra todas as nuances e implemente os procedimentos corretos no aplicativo. Em alguns casos, pode ser necessário enviar sua estratégia de registro ao serviço de segurança e obter sua aprovação ou certificação antes da operacionalização.
[1000508] ***** Incoming request from 10.244.2.168:3000 *****[1000508] Origin Id: 87d4s-a98d7-9a8742jsd -> System ID: 1000508[1000508] Request Body: { ”user_id”:”XXXXXXXXXX”, ”personal_details”:{ ”firstName”:”XXXXXXXXXX”, ”lastName”:”XXXXXXXXXX”, ”DOB”:”XXXXXXXXXX”, ”gender”:”Male”, ”proffessional”:”Software Architect”, ”industry”:”IT”, ”SSN”:”XXXXXXXXXX” }, ”address_history”:[ {”streetAdress”:”Street No 1″,”zipcode”:”XXXXX”,”state”:”CA”}, {”streetAdress”:”Street No 2″,”zipcode”:”XXXXX”,”state”:”NY”}, {”streetAdress”:”Street No 2″,”zipcode”:”XXXXX”,”state”:”AL”} ], ”card_info”:[ {”type”:”amex″,”card_number”:”XXXXXXXXX”,”credit_limit”:”XXXXX”}, {”type”:”visa″,”card_number”:”XXXXXXXXX”,”credit_limit”:”XXXXX”} ] }
Configure a nomenclatura do arquivo de log, políticas de rotação, tamanhos de armazenamento e procedimentos de backup
Se você gravar logs em arquivos, certifique-se de que eles sejam armazenados em um disco separado que não afete o aplicativo em execução de forma alguma (por exemplo, você pode alocar um volume em um servidor remoto e anexá-lo ao servidor de aplicativos). Descubra também a frequência do registro no diário e como os arquivos crescem. Certifique-se de ter uma política de rotação de log com as convenções de nomenclatura corretas (por exemplo, adicionar um carimbo de data / hora ao nome ao criar) para manter o tamanho e o número ideais de arquivos. Você também deve ter um mecanismo para fazer backup de logs antigos em um local seguro e um mecanismo para limpar o armazenamento regularmente. Dependendo do seu setor, você pode configurar um backup cronometrado (geralmente a cada poucos meses ou anos), excluindo todos os arquivos anteriores no final do período.
[ec2-user@ip-XXX-XX-X-XXX logs]$ ls .. APIM_V2_I02-2020-11-20_04:38:43.log APIM_V2_I02-2020-11-23_02:05:35.log APIM_V2_I02-2020-11-24_04:38:17.log APIM_V2_I02-2020-11-27_03:28:37.log APIM_V2_I02-2020-11-27_12:06:45.log ...
4.
Uma prática muito comum entre desenvolvedores de aplicativos corporativos é criar um servidor ou local acessível centralmente para coletar logs. Normalmente, esses agregadores rastreiam logs não apenas de aplicativos, mas também de dispositivos e sistemas operacionais (por exemplo, Linux Syslog), redes, firewalls, bancos de dados, etc. Além disso, eles separam arquivos de log de servidores de aplicativos e permitem o armazenamento de logs em mais formatos protegidos, ordenados e eficientes por mais tempo. Em alguns setores (como bancário e financeiro), é necessário armazenar logs no armazenamento local e central para que os invasores não possam obter acesso a ambos os locais e, simultaneamente, remover as evidências de suas atividades. Portanto, a redundância de dados e a incompatibilidade de dados entre os dois armazenamentos podem ajudar a detectar invasões.
Escreva analisadores e rastreie logs com prudência
A capacidade de escrever analisadores e filtros é incorporada à maioria das ferramentas de monitoramento de log - a chamada integração de gerenciamento de informações e eventos de segurança (SIEM) . Os analisadores ajudam a manter os logs em formatos mais simplificados e os dados de consulta se tornam muito mais fáceis e rápidos. Além disso, dados organizados adequadamente podem ser transferidos para sistemas de monitoramento e busca de anomalias para monitoramento proativo e previsão de eventos futuros. Essas ferramentas são muito poderosas para representar graficamente dados com base em séries temporais e em tempo real.
Configure alertas e notificações push para incidentes críticos
Quase todas as ferramentas de monitoramento de log permitem que você defina limites específicos para determinados níveis. Quando o sistema atinge esses valores, a ferramenta os detecta com antecedência, ajuda a registrar os dados e notifica os administradores de sistemas por meio de alertas, APIs de notificação push (como a API Slack Audit Logs ), e-mails etc. Eles também podem ser pré-configurados para iniciar processos automatizados. como dimensionamento dinâmico, backups de sistema, carregamento de carga e assim por diante. Mas se você investir em software comercial de monitoramento de log, dê uma boa olhada nele porque essas ferramentas podem ser exageradas para sistemas de software de pequeno a médio porte.
5. Ferramentas recomendadas
Estruturas de registro
JavaScript / TypeScript: Log4js / pino
Java: Log4j
Golang: Logrus Funções
sem servidor: aws-lambda-powertools-python / Autoescrito
Explorando, agregando e monitorando registros
Ferramentas CLI: less, vim
Cloud tools: Fluentd, AWS CloudWatch
SIEM tools: SolarWinds, Splunk, McAfee ESM, DataDog, IBM QRadar
Outros: ELK Stack (ElasticSearch, Logstash, Kibana, Beats), Loggly