스프링 부트 모니터링(Prometheus + Loki + Grafana, Docker)

2025. 6. 10. 14:14·Back-end/Spring

들어가기

AWS EC2와 같은 클라우드 서버를 이용해서 배포를 한 경우 로그를 확인하려면 번거롭게 SSH 접속을 해서 확인해야 했다. 이를 개선하기 위해 모니터링을 도입하기로 결정했다.

 

Prometheus

프로메테우스는 시계열 기반의 오픈소스 모니터링 시스템으로, 애플리케이션에서 발생하는 메트릭 데이터를 수집, 저장, 분석, 알림까지 전반적으로 처리해주는 도구이다. 주로 애플리케이션의 성능, 상태, 트래픽 등을 수치로 수집해 시각화하거나 문제가 발생했을 때 경고를 보내주는 데 사용된다.

 

Loki

로키는 Grafana Labs에서 만든 로그 수집 및 검색 시스템으로, 프로메테우스처럼 시계열 기반의 데이터를 기반으로 로그를 저장하지만, 숫자 기반의 메트릭을 저장하는 프로메테우스와 달리 로키는 문자열 기반의 로그 데이터를 처리한다.

 

Grafana

그라파나는 프로메테우스, 로키 등 다양한 데이터 소스에서 수집된 정보를 시각화하고 대시보드로 구성할 수 있는 오픈소스 툴이다.

 

모니터링 도입

의존성 추가(build.gradle)

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'com.github.loki4j:loki-logback-appender:1.4.1'

 

 

환경변수 설정(application.yml)

Spring Actuator를 통해서 프로메테우스가 필요한 메트릭 정보를 제공한다.

management:
  endpoints:
    web:
      exposure:
        include: prometheus

 

프로메테우스 설정(prometheus.yml)

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: prometheus
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['host.docker.internal:8080']

 

로그 설정(logback.xml)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProperty scope="context" name="LOKI_SERVICE" source="LOKI_SERVICE" defaultValue="{서비스명}"/>
    <springProperty scope="context" name="LOKI_ENV" source="LOKI_ENV" defaultValue="dev"/>
    <springProperty scope="context" name="HOSTNAME" source="HOSTNAME" defaultValue="localhost"/>

    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%X{requestId:-SYSTEM}] [%thread] %cyan(%logger{35}) : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- prod : host.docker.internal -->
    <springProfile name="prod">
        <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
            <http>
                <url>http://host.docker.internal:3100/loki/api/v1/push</url>
            </http>
            <format>
                <label>
                    <pattern>app=${LOKI_SERVICE},host=${HOSTNAME},level=%level</pattern>
                </label>
                <message>
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId:-SYSTEM}] l=%level h=${HOSTNAME} c=%logger{20} t=%thread | %msg %ex</pattern>
                </message>
            </format>
        </appender>
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="LOKI"/>
        </root>
    </springProfile>

    <!-- dev : localhost  -->
    <springProfile name="dev">
        <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
            <http>
                <url>http://localhost:3100/loki/api/v1/push</url>
            </http>
            <format>
                <label>
                    <pattern>app=${LOKI_SERVICE},host=${HOSTNAME},level=%level</pattern>
                </label>
                <message>
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId:-SYSTEM}] l=%level h=${HOSTNAME} c=%logger{20} t=%thread | %msg %ex</pattern>
                </message>
            </format>
        </appender>
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="LOKI"/>
        </root>
    </springProfile>
</configuration>

 

프로메테우스 + 로키 + 그라파나 도커로 실행(docker-compose.yml)

version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    ports:
      - "9090:9090"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    networks:
      - grafana-network

  loki:
    image: grafana/loki:latest
    container_name: loki
    ports:
      - "3100:3100"
    command: -config.file=/etc/loki/local-config.yaml
    volumes:
      - loki_data:/loki
    networks:
      - grafana-network

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    environment:
      - GF_SERVER_ROOT_URL={서버주소}/grafana
      - GF_SERVER_SERVE_FROM_SUB_PATH=true
      - GF_SECURITY_ADMIN_USER={초기 어드민 아이디}
      - GF_SECURITY_ADMIN_PASSWORD={초기 어드민 비밀번호}
    ports:
      - "3000:3000"
    networks:
      - grafana-network
    extra_hosts:
      - "host.docker.internal:host-gateway"

networks:
  grafana-network:
    driver: bridge

volumes:
  loki_data:

 

Nginx 설정

...
    location /grafana {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
...

 

그라파나 설정(서버주소/grafana)

docker-compose.yml에서 설정한 초기 아이디, 비밀번호로 접속

 

왼쪽 사이드바에서 Data sources로 이동

 

Prometheus 아래와 같이 입력 후 Save & test

 

Loki 아래와 같이 입력 후 Save & test

 

등록한 프로메테우스의 Build a dashboard 클릭

 

이미 잘 만들어진 대시보드를 사용하기 위해서 Import dashboard 클릭

 

19004 입력 후 Load 클릭

 

등록한 Prometheus 선택 후 Import 클릭

 

시스템 정보가 잘 나오는지 확인 후 로키 연동을 위해 Edit 클릭

 

Add -> Visualization 클릭

 

Logs 설정 후 등록한 로키를 설정하고 Code 적는 부분에 {app=서비스명} 입력한다. (이때의 서비스명은 logback.xml에 등록한 서비스 명을 입력하면 된다.)

 

모니터링 도입 완료

저작자표시 비영리 변경금지 (새창열림)
'Back-end/Spring' 카테고리의 다른 글
  • Spring JDBC Bulk Insert 알아보기
  • @RequestBody, @ResponseBody에 대해서
  • HTTP Status Code, ResponseEntity에 대해서
  • @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor에 대해서
SiwonHae
SiwonHae
프로그래밍을 공부하고 있는 학생입니다.
  • SiwonHae
    시원해의 블로그
    SiwonHae
  • 전체
    오늘
    어제
    • 전체보기 (150)
      • PS(Problem Solving) (95)
        • C (25)
        • C++ (33)
        • JAVA (37)
      • Algorithm & Data Structure (13)
      • Computer Science (12)
        • Network (2)
        • Design Pattern (10)
      • Back-end (6)
        • Spring (5)
      • Front-end (1)
        • React (1)
      • JAVA (4)
      • 정보처리기사 (17)
      • SQLD (2)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 글쓰기
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
SiwonHae
스프링 부트 모니터링(Prometheus + Loki + Grafana, Docker)
상단으로

티스토리툴바