1. π μ¬μ μ€λΉ
1.1 μμ€ν
μꡬμ¬ν
π³ Dockerμ Docker Compose μ€μΉ
β JDK 17 μ΄μ
πΎ μ΅μ 4GB RAM (κΆμ₯ 8GB μ΄μ)
π½ μ΅μ 20GB μ¬μ λμ€ν¬ 곡κ°
1.2 νμν ν¬νΈ
6379: Redis
9200: Elasticsearch
5601: Kibana
5044: Logstash
8080: Spring Boot Application
2. π οΈ ELK + Redis μ€ν μ€μ
2.1 νλ‘μ νΈ κ΅¬μ‘° μμ±
mkdir -p elk-stack && cd elk-stack
# μλΉμ€λ³ λλ ν 리 μμ±
mkdir -p redis/config \
elasticsearch/setup \
logstash/{config,pipeline} \
kibana/config
# μ€μ νμΌ μμ±
touch docker-compose.yml .env
2.2 νκ²½ λ³μ μ€μ (.env)
ELASTIC_PASSWORD =[YOUR_PASSWORD]
KIBANA_SYSTEM_PASSWORD =[YOUR_PASSWORD]
REDIS_PASSWORD =[YOUR_PASSWORD]
2.3 Docker Compose μ€μ (docker-compose.yml)
version : ' 3.8'
services :
elasticsearch :
image : elasticsearch:8.12.0
container_name : elasticsearch
environment :
- discovery.type=single-node
- xpack.security.enabled=true
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
- " ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes :
- elasticsearch_data:/usr/share/elasticsearch/data
ports :
- " 9200:9200"
networks :
- elk_network
restart : unless-stopped
kibana :
image : kibana:8.12.0
container_name : kibana
environment :
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=kibana_system
- ELASTICSEARCH_PASSWORD=${KIBANA_SYSTEM_PASSWORD}
- XPACK_ENCRYPTEDSILVEROBJECTS_ENCRYPTIONKEY=something_at_least_32_characters_long
- XPACK_SECURITY_ENCRYPTIONKEY=something_at_least_32_characters_long
- XPACK_REPORTING_ENCRYPTIONKEY=something_at_least_32_characters_long
ports :
- " 5601:5601"
networks :
- elk_network
depends_on :
- elasticsearch
restart : unless-stopped
redis :
image : redis:7.2
container_name : redis
command : redis-server --requirepass ${REDIS_PASSWORD}
ports :
- " 6379:6379"
volumes :
- redis_data:/data
networks :
- elk_network
restart : unless-stopped
logstash :
image : logstash:8.12.0
container_name : logstash
environment :
- REDIS_PASSWORD=${REDIS_PASSWORD}
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
volumes :
- ./logstash/pipeline:/usr/share/logstash/pipeline
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
ports :
- " 5044:5044"
networks :
- elk_network
depends_on :
- elasticsearch
- redis
restart : unless-stopped
networks :
elk_network :
driver : bridge
volumes :
redis_data :
elasticsearch_data :
2.4 Logstash μ€μ (logstash/pipeline/logstash.conf)
input {
redis {
host => "redis"
port => 6379
password => "${REDIS_PASSWORD}"
data_type => "list"
key => "logstash"
codec => json
}
}
filter {
if [message] =~ /^{.*}$/ {
json {
source => "message"
}
}
date {
match => [ "timestamp", "ISO8601" ]
target => "@timestamp"
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
user => "elastic"
password => "${ELASTIC_PASSWORD}"
index => "logstash-%{+YYYY.MM.dd}"
}
# λλ²κΉ
μ© μ½μ μΆλ ₯
stdout { codec => rubydebug }
}
3. π± Spring Boot μ€μ
3.1 νλ‘μ νΈ μμ±
β‘ Spring Initializr μ¬μ©
π§ Java 17 μ ν
π¦ Spring Boot 3.x μ ν
3.2 μμ‘΄μ± μΆκ° (build.gradle)
dependencies {
developmentOnly ' org.springframework.boot:spring-boot-devtools'
testImplementation ' org.springframework.boot:spring-boot-starter-test'
implementation ' org.springframework.boot:spring-boot-starter-web'
compileOnly ' org.projectlombok:lombok'
annotationProcessor ' org.projectlombok:lombok'
// Spring Data Redis
implementation ' org.springframework.boot:spring-boot-starter-data-redis'
// Logback Redis Appender
implementation ' com.cwbase:logback-redis-appender:1.1.6'
// Jedis
implementation ' redis.clients:jedis:3.1.0'
// Logback Classic
implementation ' ch.qos.logback:logback-classic'
// Logstash Logback Encoder
implementation ' net.logstash.logback:logstash-logback-encoder:7.4'
}
3.3 application.yml μ€μ
spring :
data :
redis :
host : ${SERVER_URL}
port : 6379
password : ${REDIS_PASSWORD}
logging :
config : classpath:logback-spring.xml
level :
root : INFO
com.example : DEBUG
3.4 logback-spring.xml μ€μ
<?xml version =" 1.0" encoding =" UTF-8" ?>
<configuration >
<springProperty scope =" context" name =" SERVER_URL" source =" SERVER_URL" />
<!-- μ½μ μΆλ ₯ μ€μ -->
<appender name =" CONSOLE" class =" ch.qos.logback.core.ConsoleAppender" >
<encoder >
<pattern >%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern >
</encoder >
</appender >
<!-- Redis Appender -->
<appender name =" REDIS" class =" com.cwbase.logback.RedisAppender" >
<host >${SERVER_URL}</host >
<port >6379</port >
<password >${REDIS_PASSWORD}</password >
<key >logstash</key >
<type >redis</type >
<layout class =" net.logstash.logback.layout.LogstashLayout" >
<customFields >{"application":"test"}</customFields >
</layout >
</appender >
<!-- λΉλκΈ° μ²λ¦¬λ₯Ό μν Async Appender -->
<appender name =" ASYNC_REDIS" class =" ch.qos.logback.classic.AsyncAppender" >
<appender-ref ref =" REDIS" />
<queueSize >512</queueSize >
<discardingThreshold >0</discardingThreshold >
</appender >
<root level =" INFO" >
<appender-ref ref =" CONSOLE" />
<appender-ref ref =" ASYNC_REDIS" />
</root >
<logger name =" com.example" level =" DEBUG" additivity =" false" >
<appender-ref ref =" CONSOLE" />
<appender-ref ref =" ASYNC_REDIS" />
</logger >
</configuration >
3.5 ν
μ€νΈ 컨νΈλ‘€λ¬ μμ±
@ RestController
@ RequestMapping ("/api" )
@ Slf4j
public class TestController {
@ GetMapping ("/log-test" )
public String test () {
log .info ("=== Test Start ===" );
log .debug ("Debug level test message" );
log .info ("Info level test message with data: {}" , new Date ());
log .warn ("Warning level test message" );
return "test" ;
}
}
4. βΆοΈ μ€ν λ° ν
μ€νΈ
4.1 ELK μ€ν μ€ν
4.2 Spring Boot μ€ν
4.3 λ‘κ·Έ μμ± ν
μ€νΈ
curl http://localhost:8080/api/log-test
4.4 λ‘κ·Έ νμΈ λ°©λ²
Redis λ‘κ·Έ νμΈ
docker exec -it redis redis-cli -a ${REDIS_PASSWORD}
LLEN logstash
LRANGE logstash -1 -1
Kibana λ‘κ·Έ νμΈ
π http://localhost:5601 μ μ
π Kibana > Discover λ©λ΄ μ΄λ
π μΈλ±μ€ ν¨ν΄: logstash-* μ€μ
β° μκ° λ²μ μ€μ ν μ‘°ν
5. π λ‘κ·Έ μμ§ νλ‘μΈμ€
graph LR
A[Spring Boot] -->|λ‘κ·Έ μμ±| B[Redis LIST]
B -->|μμ§| C[Logstash]
C -->|μ μ₯| D[Elasticsearch]
D -->|μκ°ν| E[Kibana]
Loading
6. π‘ μ°Έκ³ μ¬ν
π λͺ¨λ λΉλ°λ²νΈλ λ°λμ μμ νκ² κ΄λ¦¬
π νλ‘λμ
νκ²½μμλ 보μ μ€μ μΆκ° νμ
π λ©λͺ¨λ¦¬ μ€μ μ μμ€ν
νκ²½μ λ§κ² μ‘°μ
π Kibanaμμ λμ보λ ꡬμ±μΌλ‘ λͺ¨λν°λ§ κ°ν κ°λ₯
1. π μ¬μ μ€λΉ
1.1 μμ€ν μꡬμ¬ν
1.2 νμν ν¬νΈ
2. π οΈ ELK + Redis μ€ν μ€μ
2.1 νλ‘μ νΈ κ΅¬μ‘° μμ±
2.2 νκ²½ λ³μ μ€μ (.env)
2.3 Docker Compose μ€μ (docker-compose.yml)
2.4 Logstash μ€μ (logstash/pipeline/logstash.conf)
3. π± Spring Boot μ€μ
3.1 νλ‘μ νΈ μμ±
3.2 μμ‘΄μ± μΆκ° (build.gradle)
3.3 application.yml μ€μ
3.4 logback-spring.xml μ€μ
3.5 ν μ€νΈ 컨νΈλ‘€λ¬ μμ±
4.βΆοΈ μ€ν λ° ν
μ€νΈ
4.1 ELK μ€ν μ€ν
4.2 Spring Boot μ€ν
4.3 λ‘κ·Έ μμ± ν μ€νΈ
4.4 λ‘κ·Έ νμΈ λ°©λ²
Redis λ‘κ·Έ νμΈ
Kibana λ‘κ·Έ νμΈ
5. π λ‘κ·Έ μμ§ νλ‘μΈμ€
graph LR A[Spring Boot] -->|λ‘κ·Έ μμ±| B[Redis LIST] B -->|μμ§| C[Logstash] C -->|μ μ₯| D[Elasticsearch] D -->|μκ°ν| E[Kibana]6. π‘ μ°Έκ³ μ¬ν