Skip to main content

Command Palette

Search for a command to run...

Visualize Your Logs: Integrating Promtail, Loki, Prometheus, and Grafana for Improved Monitoring

Updated
4 min read
Visualize Your Logs: Integrating Promtail, Loki, Prometheus, and Grafana for Improved Monitoring

In this blog, I built a simple Laravel application that prints "Hello, World." Next, I'll set up containers for this app and then keep an eye on its logs.

Tools

To accomplish this, I utilized several tools and agents:

  • Promtail: This agent collects logs from various sources, including files and Docker containers, and forwards them to Loki. It's essentially responsible for gathering logs for storage.

  • Loki: A log aggregation system designed for efficient log storage and retrieval.

  • Grafana: An open-source analytics and monitoring platform that allows users to visualize and analyze data from multiple sources through customizable dashboards. It is commonly used for monitoring metrics, logs, and application performance.

Architecture

Compose file for Setting up containers

To set up this task, I pulled Docker images for Promtail, Loki, and Grafana. Then, I created a Compose file to run all the containers within a single network called "monitoring." Let's check out the Compose file together.

services:
  laravel-app:
    image: laravel-app
    container_name: laravel-cont
    build:
      context: /home/aditya/laravel/helloworld #Add path of dockerfile to make laravel-cont
    ports:
      - "8555:80"
    networks:
      - monitoring  # Use the monitoring network

  prometheus:
    image: prom/prometheus
    container_name: aditya-prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "8556:9090"
    command:
      - --config.file=/etc/prometheus/prometheus.yml
    networks:
      - monitoring  # Use the monitoring network

  promtail:
    image: grafana/promtail:2.7.1
    container_name: aditya-promtail
    networks:
      - monitoring  # Changed to monitoring
    volumes:
      - ./promtail-config.yaml:/etc/promtail/config.yaml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
    command: -config.file=/etc/promtail/config.yaml
    depends_on:
      - loki

  grafana:
    image: grafana/grafana
    container_name: aditya-grafana
    ports:
      - "8557:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    networks:
      - monitoring  # Use the monitoring network
    depends_on:
      - prometheus
      - loki

  loki:
    image: grafana/loki
    container_name: aditya-loki
    volumes:
      - ./loki-config.yaml:/etc/loki/loki-config.yaml
    command: -config.file=/etc/loki/loki-config.yaml
    ports:
      - "8558:3100"
    networks:
      - monitoring  # Use the monitoring network

volumes:
  postgres_data:
  grafana_data:
  loki-data:

networks:
  monitoring:
    driver: bridge

Here's the Docker file located at /home/aditya/laravel/helloworld

FROM php:8.2-apache

# Install dependencies
RUN apt-get update && \
    apt-get install -y \
    libzip-dev \
    zip

# Enable mod_rewrite
RUN a2enmod rewrite

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql zip

ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

# Copy the application code
COPY . /var/www/html

# Set the working directory
WORKDIR /var/www/html

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Install project dependencies
RUN composer install

# Set permissions
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache

Note: Make sure you have a laravel-app that contains all necessary files.

In the same directory where the Compose file is located, please add the following files:

1. prometheus.yml

Purpose: This file configures Prometheus to scrape metrics from Loki. It defines the scrape interval and specifies the targets for monitoring.

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'loki'
    static_configs:
      - targets: ['loki:3100']

2. loki-config.yml

Purpose: This configuration file sets up Loki's parameters, such as the server port, storage configurations, and ingester settings. It determines how logs are stored and indexed.

auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  wal:
    enabled: true
    dir: /loki/wal
  chunk_idle_period: 1m
  max_chunk_age: 1h

schema_config:
  configs:
    - from: 2020-10-01
      store: boltdb-shipper
      schema: v11
      index:
        prefix: index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /loki/index
    cache_location: /loki/cache
    shared_store: filesystem
  filesystem:
    directory: /loki/chunks

limits_config:
  max_query_series: 500000

3. promtail-config.yaml

Purpose: This file configures Promtail to scrape logs from the specified locations (like Docker containers) and send them to Loki. It also sets the server port and the position file to keep track of the last read log positions.

server:
  http_listen_port: 9080

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://aditya-loki:3100/loki/api/v1/push


scrape_configs:
  - job_name: docker
    static_configs:
      - targets:
          - localhost
        labels:
          job: docker
          __path__: /var/lib/docker/containers/*/*.log  # Path to Docker logs

Now, set up containers using Docker Compose file.

command:

docker-compose build

docker-compose up -d (run containers in detached mode)

Accessing the containers:

Laravel application: http://server-ip:8555

Prometheus: http://server-ip:8556

Grafana: http://server-ip:8557

Add loki as datasource

In the URL, make sure to enter the right container name and port.

Visualize logs using the filename and containerID

Here, in the directory /var/lib/docker/, you'll find the ID for each container, and you can easily forward their logs to Loki.

Oh, wait! In my upcoming blog, I'll dive deeper into this topic and also include a step-by-step guide on setting up alerts. Make sure to check it out!