Post

πŸ’Ž ELK Β· API Gateway Β· Logback 쀑앙 κ΄€λ¦¬μž μ„œλ²„ ꡬ좕

πŸ’Ž ELK Β· API Gateway Β· Logback 쀑앙 κ΄€λ¦¬μž μ„œλ²„ ꡬ좕

ELK Β· API Gateway λ„μž… κ·Όκ±°

βœ… ELK

  • μ‹œμŠ€ν…œκ³Ό μ„œλΉ„μŠ€ 둜그λ₯Ό μ€‘μ•™μ—μ„œ 톡합 μˆ˜μ§‘ 및 μ €μž₯ν•  수 μžˆλ‹€.
  • Kibanaλ₯Ό 톡해 μ‹€μ‹œκ°„ λŒ€μ‹œλ³΄λ“œ 및 μ‹œκ°ν™”λ₯Ό κ΅¬μ„±ν•˜μ—¬ 운영 ν˜„ν™©μ„ λͺ¨λ‹ˆν„°λ§ ν•  수 μžˆλ‹€.
  • μ„œλΉ„μŠ€ μž₯μ• λ‚˜ 였λ₯˜ λ°œμƒ μ‹œ, 둜그 검색을 톡해 λΉ λ₯΄κ²Œ 원인을 νŒŒμ•…ν•˜κ³  λŒ€μ‘ν•  수 μžˆλ‹€.

βœ… API Gateway

  • JWT 인증 및 인가λ₯Ό μ „λ‹΄ν•  수 μžˆλ‹€.
  • λ„ˆλ¬΄ λ§Žμ€ μš”μ²­μ„ λ³΄λ‚΄λŠ” ν΄λΌμ΄μ–ΈνŠΈλ₯Ό 차단 및 μ œμ–΄ κ°€λŠ₯ν•˜λ‹€.
  • API 버전 관리 κ°€λŠ₯ν•˜λ‹€.
  • μ„œλΉ„μŠ€ 별 μƒμ΄ν•œ API 계약을 ν‘œμ€€ν™” ν•˜μ—¬ 외뢀에 μ œκ³΅ν•œλ‹€.

βœ… Logback

  • 둜그 파일 둀링 및 보쑴 섀정이 μœ μ—°ν•˜κ²Œ κ°€λŠ₯ν•˜λ‹€.

μ½”λ“œ μž‘μ„±

βœ… ELK Docker-compose.yml 및 μ„€μ • 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# docker-compose.yml
services:
  elasticsearch:
Β Β   image: docker.elastic.co/elasticsearch/elasticsearch:7.17.18
Β Β   container_name: elasticsearch
Β Β   environment:
Β Β     - discovery.type=single-node
Β Β     - ES_JAVA_OPTS=-Xms512m -Xmx512m
Β Β   volumes:
Β Β     - esdata:/usr/share/elasticsearch/data
Β Β   ports:
Β Β     - "9200:9200"
Β Β   networks:
Β Β     - efk
Β 
Β  kibana:
    image: docker.elastic.co/kibana/kibana:7.17.18
    container_name: kibana
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch
    networks:
      - efk

  logstash:
    image: docker.elastic.co/logstash/logstash:7.17.18
    container_name: logstash
    volumes:
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
      - ./logstash/pipeline:/usr/share/logstash/pipeline
      - ./sentinel-app/logs:/app/logs
    ports:
      - "5044:5044"
      - "9600:9600"
    depends_on:
      - elasticsearch
    networks:
      - efk

  gateway:
    build:
      context: ./sentinel-app
    container_name: sentinel-app
    ports:
      - "8080:8080"
    volumes:
      - ./sentinel-app/logs:/app/logs
    networks:
      - efk

volumes:
  esdata:

networks:
  efk:
Β Β 
# logstash.yml 
http.host: "0.0.0.0"
xpack.monitoring.enabled: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# logstash.conf
input {
  file {
	path => "/app/logs/*.log"
	start_position => "beginning"
	sincedb_path => "/dev/null"
	codec => json
  }
}

filter {
  mutate {
	add_field => {
	  "log_message" => "%{message}"
	  "server_role" => "gateway"
	}
	remove_field => ["parsed", "host", "path", "message"]
  }
}

output {
  elasticsearch {
	hosts => ["http://elasticsearch:9200"]
	index => "sentinel-logs-%{+YYYY.MM.dd}"
  }

  stdout {
	codec => rubydebug
  }
}

Logback μ„€μ • 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# logback-spring.xml
<configuration>
	<include resource="net/logstash/logback/logback.xml"/>
	<property name="LOG_PATH" value="./logs"/>
	
	<appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOG_PATH}/app-%d{yyyy-MM-dd}.log</fileNamePattern>
			<maxHistory>30</maxHistory>
		</rollingPolicy>
		<encoder class="net.logstash.logback.encoder.LogstashEncoder">
			<fieldNames>
				<timestamp>@timestamp</timestamp>
				<level>level</level>
				<logger>logger</logger>
				<thread>thread</thread>
				<message>message</message>
			</fieldNames>
		</encoder>
	</appender>
	
	<root level="INFO">
		<appender-ref ref="JSON_FILE"/>
	</root>
</configuration>
  • Logback을 μ‚¬μš©ν•˜μ—¬ 둜그 νŒŒμΌμ„ μƒμ„±ν•œλ‹€.
  • <include resource="net/logstash/logback/logback.xml"/> 라인을 톡해 Logstash에 λ§žλŠ” JSON ν˜•μ‹μ˜ 둜그 νŒŒμΌμ„ 좜λ ₯ν•œλ‹€.
  • <encoder class="net.logstash.logback.encoder.LogstashEncoder"> ... </encoder> 라인을 톡해 둜그의 각 ν•­λͺ©μ„ λ‚˜νƒ€λ‚Έλ‹€.
  • 이 ν•­λͺ©λ“€μ€ Elasticsearchμ—μ„œ 필터링 ν•  수 μžˆλŠ” Metadataκ°€ λ˜λŠ” 것이닀.
  • LogstashλŠ” 둜그 νŒŒμΌμ„ 읽어 Elasticsearch둜 μ „λ‹¬ν•œλ‹€.
  • logstash.yml의 http.host ν‚€λ₯Ό 톡해 타 μ„œλ²„μ—μ„œλ„ 둜그λ₯Ό 전솑할 수 μžˆλ‹€.
  • logstash.conf 섀정을 톡해 가곡 및 필터링 ν•˜μ—¬ 인덱슀둜 생성 및 데이터λ₯Ό μ£Όμž…ν•œλ‹€.

βœ… API Gateway μ„€μ • 파일일

1
implementation 'org.springframework.cloud:spring-cloud-starter-gateway:4.2.0'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# application.yml
spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: 332-project-management-service
          uri: http://127.0.0.1:8081
          predicates:
            - Path=/project-management/**
          filters:
            - StripPrefix=1

        - id: 332-service-desk
          uri: http://127.0.0.1:8082
          predicates:
            - Path=/service-desk/**
          filters:
            - StripPrefix=1

server:
  port: 8080
  • Spring Cloud Gatewayλ₯Ό μ‚¬μš©ν–ˆλ‹€.
  • predicates ν‚€λ₯Ό 톡해 경둜 Endpointλ₯Ό μ„€μ •ν–ˆλ‹€.
  • filters ν‚€μ˜ StripPrefix=1 값을 톡해 predicates ν‚€μ—μ„œ μ„€μ •ν•œ μ—”λ“œν¬μΈνŠΈμ˜ /**을 μ‹€μ œ API μš”μ²­ 경둜둜 μ§€μ •ν–ˆλ‹€.
  • κ°€λ Ή http://localhost:8080/project-management/project둜 POST λ”°μœ„μ˜ μš”μ²­μ΄ λ“€μ–΄μ˜€λ©΄ API Gatewayκ°€ μš”μ²­μ„ http://localhost:8081/project둜 Redirect ν•œλ‹€.Β 

둜그 뢄석

βœ… ν”„λ‘œμ νŠΈ μ‹€ν–‰ 및 둜그 파일 확인

βœ… Kibana UI 확인

  • 둜그 파일과 λ™μΌν•œ μΌμžμ— 데이터가 μ‘΄μž¬ν•˜λŠ” 것을 확인할 수 μžˆλ‹€.

  • logback-spring.xmlμ—μ„œ level을 ν•„λ“œμ— μΆ”κ°€ν–ˆκΈ° λ•Œλ¬Έμ— Elasticsearch 및 Kibanaμ—μ„œ 둜그 레벨 별 필터링을 ν•  수 있게 λ˜μ—ˆλ‹€.

회고

  • 이제 κΈ°μ‘΄ ν”„λ‘œμ νŠΈλ“€μ˜ JWT 인증 λ‘œμ§μ„ API Gateway μ„œλ²„μ—μ„œ μ „λ‹΄ν•˜λ„λ‘ μˆ˜μ •ν•΄μ•Ό ν•œλ‹€.
  • λ˜ν•œ ν”„λ‘œμ νŠΈλ“€μ˜ 둜그λ₯Ό API Gateway μ„œλ²„λ‘œ μ „μ†‘ν•˜μ—¬ 톡합 κ΄€λ¦¬ν•˜λ„λ‘ μˆ˜μ • ν•  것이닀.
This post is licensed under CC BY 4.0 by the author.