my application's services are deployed via docker-compose. Currently, I also deployed Grafana, Loki and Promtail within the same docker-compose network.
Following the getting-started guide, collecting and displaying the log files from /var/log with the config
- job_name: system
entry_parser: raw
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
works fine.
However, my backend logs (NestJS) into a log file which is stored in a docker volume.
Example log entry:
{"message":"Mapped {/api/drink, POST} route","context":"RouterExplorer","level":"info","timestamp":"2021-03-23T17:08:16.334Z"}
The path to the log is
/var/lib/docker/volumes/my_volume/_data/general.log
When I add the following config to Promtail
- job_name: backend
pipeline_stages:
- json:
expressions:
level: level
message: message
timestamp: timestamp
context: context
static_configs:
- targets:
- localhost
labels:
job: backend
__path__: /var/lib/docker/volumes/my_volume/_data/general.log
and use the query {job="backend"} in Grafana, nothing is displayed.
Furthermore, the log of the promtail container doesn't give any information.
What am I missing?
Thank you in advance!
In your pipeline stages you need to store the extracted values:
pipeline_stages:
- json:
expressions:
level: level
message: message
timestamp: timestamp
context: context
- timestamp:
source: timestamp
- labels:
level:
context:
- output:
source: message
This will set the timestamp, the labels context, level and the message will be the log line.
Documentation can be found here.
Related
How can I get logs from docker events to Promtail?
I'm using Docker to run a set of containers on my server, and I would like to collect and centralize their logs using Promtail. Specifically, I would like to capture logs from the docker events(logs from the docker daemon about when the container is started, etc. ) command and send them to Promtail.
How can I achieve this? What are the steps and configurations I need to set up in order to get logs from docker events to Promtail?
Note that my Docker host is running on a Windows machine, and I'm using the latest version of Promtail.
my promtail.yaml file :
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: flog_scrape
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: label
values: ["logging=promtail"]
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
- source_labels: ['__meta_docker_container_label_logging_jobname']
target_label: 'job'
Any help or advice would be greatly appreciated. Thank you!
I am scraping logs from docker with Promtail to Loki.
Works very well, but I would like to remove timestamp from log line once it has been extracted by Promtail.
The reason is that I end up with log panel that half of screen is occupied by timestamp. If I want to display timestamp in panel, I can do that, so I dont really need it in log line.
I have been reading documentation, but not sure how to approach it. logfmt? replace? timestamp?
https://grafana.com/docs/loki/latest/clients/promtail/stages/logfmt/
promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
# local machine logs
- job_name: local logs
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
# docker containers
- job_name: containers
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 15s
pipeline_stages:
- docker: {}
relabel_configs:
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
regex: '(.*)'
target_label: 'service'
Thank you
Actually I just realized I was looking for wrong thing. I just wanted to display less logs in Grafana, logs were formatted properly. I just had to select fields to display.
Thanks!
I want to run filebeat as a sidecar container next to my main application container to collect application logs. I'm using docker-compose to start both services together, filebeat depending on the application container.
This is all working fine. I'm using a shared volume for the application logs.
However I would like to collect docker container logs (stdout JSON driver) as well in filebeat.
Filebeat provides a docker/container input module for this purpose. Here is my configuration. First part is to get the application logs. Second part should get docker logs:
filebeat.inputs:
- type: log
paths:
- /path/to/my/application/*.log.json
exclude_lines: ['DEBUG']
- type: docker
containers.ids: '*'
json.message_key: message
json.keys_under_root: true
json.add_error_key: true
json.overwrite_keys: true
tags: ["docker"]
What I don't like it the containers.ids: '*'. Here I would want to point filebeat to the direct application container, ignoring all others.
Since I don't know the container ID before I run docker-compose up starting both containers, I was wondering if there is a easy way to get the container ID from my application container in my filebeat container (via docker-comnpose?) to filter on this ID?
I think you may work around the problem:
first set all the logs from the contianer to a syslog:
driver: "syslog"
options:
syslog-address: "tcp://localhost:9000"
then configure filebeat to get the logs from that syslog server like this:
filebeat.inputs:
- type: syslog
protocol.udp:
host: "localhost:9000"
This is also not really answering the question, but should work as a solution as well.
The main idea is to use label within the filebeat autodiscovery filter.
Taken from this post: https://discuss.elastic.co/t/filebeat-autodiscovery-filtering-by-container-labels/120201/5
filebeat.yml
filebeat.autodiscover:
providers:
- type: docker
templates:
- condition:
contains:
docker.container.labels.somelabel: "somevalue"
config:
- type: docker
containers.ids:
- "${data.docker.container.id}"
output.console:
pretty: true
docker-compose.yml:
version: '3'
services:
filebeat:
image: docker.elastic.co/beats/filebeat:6.2.1
command: "--strict.perms=false -v -e -d autodiscover,docker"
user: root
volumes:
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml
- /var/lib/docker/containers:/var/lib/docker/containers
- /var/run/docker.sock:/var/run/docker.sock
test:
image: alpine
command: "sh -c 'while true; do echo test; sleep 1; done'"
depends_on:
- filebeat
labels:
somelabel: "somevalue"
I have a Prometheus setup that monitors metrics exposed by my own services. This works fine for a single instance, but once I start scaling them, Prometheus gets completely confused and starts tracking incorrect values.
All services are running on a single node, through docker-compose.
This is the job in the scrape_configs:
- job_name: 'wowanalyzer'
static_configs:
- targets: ['prod:8000']
Each instance of prod tracks metrics in its memory and serves it at /metrics. I'm guessing Prometheus picks a random container each time it scraps which leads to the huge increase in counts recorded, building up over time. Instead I'd like Prometheus to read /metrics on all instances simultaneously, regardless of the amount of instances active at that time.
docker-gen (https://github.com/jwilder/docker-gen) was developed for this purpose.
You would need to create a sidecart container running docker-gen that generates a new set of targets.
If I remember well the host names generated are prod_1, prod_2, prod_X, etc.
I tried a lot to find something to help us with this issue but it looks an unsolved issue.
So, I decided to create this tool that helps us with this service-discovery.
https://github.com/juliofalbo/docker-compose-prometheus-service-discovery
Feel free to contribute and open issues!
You can use DNS service discovery feature. For example:
docker-compose.yml:
version: "3"
services:
myapp:
image: appimage:v1
restart: always
networks:
- back
prometheus:
image: "prom/prometheus:v2.32.1"
container_name: "prometheus"
restart: "always"
ports: [ "9090:9090" ]
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
- "prometheus_data:/prometheus"
networks:
- back
prometheus.yml sample:
global:
scrape_interval: 15s
evaluation_interval: 60s
scrape_configs:
- job_name: 'monitoringjob'
dns_sd_configs:
- names: [ 'myapp' ] <-- service name from docker-compose
type: 'A'
port: 8080
metrics_path: '/actuator/prometheus'
You can check your DNS records using nslookup util from any container in this network:
docker exec -it myapp bash
bash-4.2# yum install bind-utils
bash-4.2# nslookup myapp
Server: 127.0.0.11
Address: 127.0.0.11#53
Non-authoritative answer:
Name: myapp
Address: 172.22.0.2
Name: myapp
Address: 172.22.0.7
I am trying to configure a docker-compose.yml (I am aware version and services is not stated, they are apart of the file) file to run a neo4j instance. I am using docker swarm and deploying a stack i.e. used the following commands:
docker swarm init
docker stack deploy -c docker-compose.yml neo
note_db:
image: neo4j:latest
environment:
- NEO4J_AUTH=<username>/<password>
- NEO4J_dbms_mode=CORE
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_connector_http_listen__address=:7474
- NEO4J_dbms_connector_https_listen__address=:6477
- NEO4J_dbms_connector_bolt_listen__address=:7687
ports:
- "7474:7474"
- "6477:6477"
- "7687:7687"
volumes:
- type: bind
source: ~/neo4j/data
target: /data
- type: bind
source: ~/neo4j/logs
target: /logs
deploy:
replicas: 1
resources:
limits:
cpus: "0.1"
memory: 120M
restart_policy:
condition: on-failure
I have omitted the username and password. I am currently only trying to spin up one instance as I am still testing. I have removed NEO4J_AUTH as well as NEO4J_AUTH=none, with the same outcome.
The logs provide the following:
org.neo4j.commandline.admin.CommandFailed: initial password was not set because live Neo4j-users were detected., at org.neo4j.commandline.admin.security.SetInitialPasswordCommand.setPasswor (SetInitialPasswordCommand.java:83)
command failed: initial password was not set because live Neo4j-users were detected.,
Starting Neo4j.,
2018-09-17 16:12:39.396+0000 INFO ======== Neo4j 3.4.7 ========,
2018-09-17 16:12:41.990+0000 INFO Starting...,
2018-09-17 16:12:43.792+0000 ERROR Failed to start Neo4j: Starting Neo4j failed: Component 'org.neo4j.server.database.LifecycleManagingDatabase#70b0b186' was successfully initialized, but failed to start. Please see the attached cause exception "/logs/debug.log (Permission denied)".
In the debug.log file, the only things I found is :
[o.n.b.s.a.BasicAuthentication] Failed authentication attempt for 'neo4j' (no other failures, errors or warnings).
Clearly, I have some sort of auth issue but I am not sure where the error lies and how to address it. I have attempted NEO4J_AUTH=none and removing the ENV completely, it still does not work.
Someone has posted something along the lines of this issue but they haven't received any responses. I am hoping mine does.
FROM user: logisima
You don't have any issue with auth, it's a permission issue : cause exception "/logs/debug.log (Permission denied)"