이제 fluentd의 다양한 plugin들을 사용하여 로그들을 파싱하고 고도화해보도록 하자.
kubernetes에서는 docker지원을 공식 중단했다. 이유는 간단한데, 공식 CRI를 docker에서 미지원했기 때문이다.
이때 바뀌게 되는 부분이 하나 있는데, 바로 log
format이다. 기존의 docker에서 지원하는 log format은 다음과 같은 json
형식이다.
{"log":"INFO: \"GET /healthcheck HTTP/1.1\" 200 OK\n","stream":"stdout","time":"2023-12-07T06:56:33.076295527Z"}
따라서, fluentd를 사용할 때 source
부분의 parse
plugin으로 json
을 사용하는 것이다.
<source>
@type tail
@id in_tail_container_logs
path "/var/log/pods/*/*/*.log"
pos_file "/var/log/fluentd-containers.log.pos"
read_from_head true
tag "**"
format json
time_format %Y-%m-%dT%H:%M:%S.%NZ
<parse>
time_format %Y-%m-%dT%H:%M:%S.%NZ
@type json
time_type string
</parse>
</source>
json
으로 된 log data는 fluentd에서 기가막히게 parsing하지만, 안타깝게도 containerd, cri-o에서의 log format은 json
이 아니다.
2023-12-07T06:56:33.076295527Z stdout F INFO: "GET /healthcheck HTTP/1.1" 200 OK
정리하면 다음과 같다.
<time> <stream> <logtag> <log>
F
이후로는 모두 log
이다. <time>
, <stream>
, <logta>
, <log>
사이는 모두 빈 칸이 하나씩이다. 따라서, 위의 docker
에서 parsing하던 json
으로 해당 log를 parsing하면 다음의 에러만 반복될 것이다.
ParserError error="pattern not matched with data"
따라서, 다음과 같이 regular expression을 사용해주도록 하자.
<source>
@type tail
@id in_tail_container_logs
path "/var/log/pods/*/*/*.log"
pos_file "/var/log/fluentd-e2term-pod.log.pos"
read_from_head true
tag "**"
<parse>
@type multi_format
<pattern>
format regexp
time_key time
time_format %Y-%m-%dT%H:%M:%S.%N%Z
expression /^(?<time>.+) (?<stream>stdout|stderr) (?<logtag>.)? (?<log>.*)/
</pattern>
</parse>
</source>
위의 regular expression으로 crio, containerd의 log를 parsing하면 된다. record로 time
, stream
, logtag
, log
가 저장된다. 다행인 것은 time
의 format이 docker
일 때와 동일하기 때문에 이전과 동일한 time_format
을 쓰면 된다.
결과로 다음과 record가 만들어지게 된다.
{
"time": "2023-12-07T06:56:33.076295527Z",
"stream": "stdout",
"logtag": "F",
"log": "INFO: \"GET /healthcheck HTTP/1.1\" 200 OK"
}
log를 파싱하여 원하는 형식으로 record를 만들어주는 것이 좋다. 그래야 elasticsearch에서 검색하기가 좋기 때문이다.
log가 json
으로 되어있다면 아주 happy한 경우이다. 다음과 같은 filter만 만들어주면 되기 때문이다.
<filter **>
@type parser
key_name log
<parse>
@type json
json_parser json
</parse>
replace_invalid_sequence true
emit_invalid_record_to_error false
reserve_data true
</filter>
record key로 log
를 json
으로 parsing하겠다는 것이다. 그러나 모든 pod의 log가 json
으로 되어있지 않을 수 있으므로 emit_invalid_record_to_error
는 false
로 두어서 parsing이 안되더라도 error로 남기지 않도록 한다. 또한, reserve_data
는 true
로 하여, log를 parsing 후에도 원본을 record에 남기도록 한다.
만약, log가 공백과 같은 특별한 구분자를 통해 형식화되었다면 regular expression을 사용하는 것이 좋다. 가령 다음의 log형식을 갖는다고 하자.
2023-12-07T06:56:33.076295527Z INFO original:96 Failed to read files.
위의 log를 형식화하면 다음과 같다.
<time>\t<level>\t<caller>\t<log>
다음과 같이 filter
를 통해서 regular expression으로 log를 parsing할 수 있다.
<filter **>
@type parser
key_name log
<parse>
@type regexp
expression /^(?<time>.+)\t(?<level>.+)\t(?<caller>.+)\t(?<log>.*)/
time_format %Y-%m-%dT%H:%M:%S.%N%Z
</parse>
</filter>
record결과로 다음과 같이 나오게 된다.
{
"time": "2023-12-07T06:56:33.076295527Z",
"level": "INFO",
"caller": "original:96",
"log": "Failed to read files."
}
만약, 특정 record field를 추가하거나, 삭제하고 싶다면 record_transformer
를 사용하면 된다.
<filter **>
@type record_transformer
enable_ruby
remove_keys $.content.time
<record>
tag ${tag}
</record>
</filter>
다음의 경우에는 record
의 field로 content.time
을 삭제하고, tag
field를 만들어 놓는다. tag
field값은 fluentd
에서 사용하는 tag
가 되는 것이다.
주의: 조심해할 것 중 하나는 parsing을 한 다음에 record에 특정 field를 삭제, 추가, 변경하는 것이 좋다. 만약 특정 field를 추가, 삭제, 변경한 다음에 parsing이 이루어지면, 변동사항은 남지않고 parsing된 결과가 덮어써지게 되는 수가 있다. 가령 위에서
tag
를 추가한다음log
를 parsing하면tag
field가 사라지게 된다.
이제 배포해서 사용하면 문제없이 구동될 것 같지만, 한 가지 문제가 남아있다. 바로 rollover
이다. rollover
가 무엇이냐하면, 현재 log를 받고 있는 elasticsearch index를 김밥마냥 말아(roll)버린다음에 저장하고, 새로운 index를 만들어 log들을 받겠다는 것이다.
[2023/12/06] pod logs -> fluentd -> elasticsearch -> index: server-000001
[2023/12/07] pod logs -> fluentd -> elasticsearch -> index: server-000002 (rollover: server-000001)
rollover된 index는 그냥 놔두거나 삭제할 수 있다. 일반적으로 data engineering에서 이러한 작업을 retention
이라고 한다.
이렇게 rollover
를 하는 이유는 아주 간단한데, 계속해서 index를 만들어 log를 저장하기에는 하드디스크의 자원이 한정적이기 때문이다.
elasticsearch에서 rollover
는 직접 API를 사용해 요청을 보낼 수 있지만, 공식적으로는 ILM(index lifecycle management)를 적용해서 rollover
가 자동으로 이루어지도록 추천하고 있다.
ILM
은 index를 hot-warm-cold-frozen-delete
페이즈로 구분하여 관리하고 지정한 기간이 지나면 phase를 전황시키고 지정한 작업을 수행하도록 한다.
가령, 다음과 같이 설정할 수 있다. index가 처음 생성되면 hot
phase로 넘어가고 하루 단위 또는 4GB의 index가 넘어가면 rollover시키도록 한다. rollover로 넘어간 index는 hot
에서 warm
phase로 넘아가도록 하고 warm
phase에서는 읽기 전용으로 바꾸도록 한다. 생성한 지 7일이 지나면 cold
phase로 넘어가도록 하며, cold
phase로 넘어간 index는 저장만 하는 node로 이동시키도록 한다. 생성된 지 30일이 지난 index는 delete
phase로 가도록 하며, delete
phase로 전환된 index는 snapshot으로 백업되며 완료 후 삭제하도록 한다. (단, snapshot 저장은 유료 엔터프라이즈에서만 가능하다.)
각 phase의 컨셉을 정리하면 다음과 같다.
위의 phase는 공식 홈페이지에서 제안하는 phase일 뿐이지, 각 phase를 개인마다 다르게 관리해도 문제될 것은 없다.
이 phase로 넘어가는 단계의 조건는 시간과 용량이다. 가령 hot
phase에서 6분 후에 delete
phase로 보내거나, hot
phase에서 10G
가 넘어가면 delete
phase로 넘기자는 것이다.
그런데 이 ILM에서 조심해야할 것이 있는데, 바로 ILM을 API를 통해 직접 index에 하나하나 적용시켜줄 수도 있지만 일반적으로 index-template
를 할당해서 index-template
의 pattern을 따르는 index만 ILM을 따르도록 할 수 있다.
|----------Index-------|
| server-1, server-2 | <---------index template(index pattern) <--------- ILM(rollover)
|----------------------|
index-template
는 index
의 pattern위주니까 index
의 이름들이 server*
라는 pattern을 따르고, server*
index pattern을 가지는 index-template
에 ILM
을 할당해주면 자동으로 server-1
, server-2
들이 모두 rollover되겠지?? 싶지만 안된다.
안되는 이유에는 몇 가지 이유가 있다.
1. index의 이름은 마지막에 -{숫자}
로 끝나야 한다. 가령 server-1-000001
이렇게 끝나야 한다. 만약 해당 규칙을 안따르면 illegal_argument_exception: index name does not match pattern '^.*-\d+$'
가 발생한다.
2. rollover
는 index
이름이 아니라, alias
로 결정된다. 따라서, index-template
의 index pattern
을 따르고 있는 index
들이라도 alias
가 index template
에서 지정한 rollover_alias
이어야 한다. 주의할 것은 index-template
에서도 aliases
를 설정할 수 있는데, 해당 부분의 alias
이름이 rollover_alias
이름과 동일하면 안된다.
정리하면 다음과 같다.
index template(index pattern: server*, rollover_alias: server) <--------- ILM(rollover)
|
↓
|---------------------Index------------------------|
| server-1(alias: server), server-2(alias: park) |
|--------------------------------------------------|
위의 예시와 같이 index template
가 pattern
으로 server*
를 가지고 있어서 server-1
, server-2
index가 모두 적용된 것을 알 수 있다. 그리고 index template
는 ILM
과 연결되어있는데, ILM에서 rollover
를 수행한다고 하자.
문제는 server-1
, server-2
모두 index template
의 pattern을 따르지만, rollover_alias
는 server
만 해당하기 때문에 server-1
은 alias
가 server
라 적용되는 반면 server-2
는 alias
가 park
이라서 반영되지 않는다.
따라서, index마다 alias
를 rollover ILM이 달린 index template
의 rollover_alias
로 설정해주어야 한다는 것이다.
그런데, 이걸 어떻게 fluentd에서 할 수 있는가?? 라고 한다면 막막하다. 이를 위해서 어느 2020년 용자가 issue를 만들고 contribution을 해주었다. https://github.com/uken/fluent-plugin-elasticsearch/issues/752
결론만 만들자면 자동으로 ILM을 만들고 index-template를 만들며, index에 rollover_alias
와 동일한 alias
를 달아준다. 이 덕분에 자동으로 rollver가 동작하도록 한다는 것이다.
fluentd
의 elasticsearch
plugin을 사용하면 되는데, docs만 봤다가는 적어도 일주일간 눈물의 삽질을 해야한다. 다음의 예시를 보고, 만들면 된다.
<match **>
@type elasticsearch
host $HOST_IP
port $HOST_PORT
log_es_400_reason true
logstash_format true
logstash_prefix server
type_name fluentd
application_name server
template_name index-template
template_file /fluentd/etc/index_template.json
enable_ilm true
ilm_policy_id retention-3m
ilm_policy {"policy":{"phases":{"hot":{"min_age":"0ms","actions":{"rollover":{"max_age":"3m","max_size":"5gb"}}},"delete":{"min_age":"3m","actions":{"delete":{}}}}}}
ilm_policy_overwrite false
</match>
뭔가 복잡하지만 ILM
에 관련된 부분만 차례대로 보면 다음과 같다.
1. enable_ilm
: default가 false
인데 true
로 바꾸지 않으면 구동되지 않는다.
2. ilm_policy_id
: 생성할 ILM이름이다.
3. ilm_policy
: ILM policy이다. elasticsearch에서 적용하는 ILM
json형식과 동일하다. 참고로, 위의 예시는 rollover가 잘되는 지를 확인하기 위해 3분마다 rollover가 이루어지고 rollover된 index는 3분 뒤에 삭제된다는 의미이다.
4. ilm_policy_overwrite
: 이름이 동일한 경우, overwrite할 것인지를 묻는다. 만약 false
일 때, 이름이 동일한 ILM이 있다면 기존의 ILM을 적용하고 새로 만들지 않는다.
5. template_name
: 생성할 index-template
이름이다. 그러나 동작하지 않는 것으로 보이지만, 없으면 안만들어질 수도 있다. docs에는 기존에 template_name
으로 index-template
가 있다면 이를 적용한다고 하지만, 실제로 해봤는데 잘안된다...
6. template_file
: 생성할 index-template
의 정의가 있는 path이다.. elasticsearch와 동일한 정의를 가지는데, 그닥 중요한 부분은 없다. rollover_alias
알아서 만들어주고 생성될 index
와의 맵핑도 자동으로 해준다. 단, 없으면 rollover적용이 안된다
kibana에서 template를 만들 때는 다음과 같다.
{
"template": {
"settings": {
"index": {
"lifecycle": {
"name": "template",
"rollover_alias": "retention"
}
}
},
"aliases": {},
"mappings": {}
}
}
그런데 굳이 이렇게까지 만들 필요는 없다. elasticsearch plugin에서 자동으로 lim
도 만들어주고 그 정보를 이용해서 template
에 rollover_alias
, name
등을 다 설정해준다.
index_template.json
의 정의는 다음과 같았다.
{
"index_patterns": [
"logstash-default*"
],
"settings": {
"index": {
"number_of_replicas": "1"
}
}
}
해당 index_template.json
을 fluentd
pod의 /etc/fluentd/index_template.json
에 제공해야하므로 ConfigMap
에 추가하고 Volume
에 추가해야한다.
따라서 최종 daemonset은 다음과 같다.
apiVersion: v1
kind: Namespace
metadata:
name: fluentd
---
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: fluentd
data:
index_template.json: |-
{
"settings": {
"index": {
"number_of_replicas": "1"
}
}
}
fluent.conf: |-
<source>
@type tail
@id in_tail_container_logs
path "/var/log/pods/*/*/*.log"
pos_file "/var/log/fluentd-log.pos"
read_from_head true
tag "**"
<parse>
@type multi_format
<pattern>
format regexp
time_key time
time_format %Y-%m-%dT%H:%M:%S.%N%Z
expression /^(?<time>.+) (?<stream>stdout|stderr) (?<logtag>.)? (?<log>.*)/
</pattern>
</parse>
</source>
<filter **>
@type parser
key_name log
<parse>
@type json
json_parser json
</parse>
replace_invalid_sequence true
emit_invalid_record_to_error false
reserve_data true
</filter>
<match **>
@type elasticsearch
host ${ELASTICSEARCH_HOST_IP}
port ${ELASTICSEARCH_HOST_REST_PORT}
log_es_400_reason true
logstash_format true
logstash_prefix ${LOGSTASH_INDEX_PREFIX}
type_name fluentd
application_name ${APP_NAME}
template_name index_template
template_file /fluentd/etc/index_template.json
enable_ilm true
ilm_policy_id retention-3m
ilm_policy {"policy":{"phases":{"hot":{"min_age":"0ms","actions":{"rollover":{"max_age":"3m","max_size":"5gb"}}},"delete":{"min_age":"3m","actions":{"delete":{}}}}}}
ilm_policy_overwrite false
</match>
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: fluentd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: fluentd
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: fluentd
labels:
k8s-app: fluentd-logging
version: v1
spec:
selector:
matchLabels:
k8s-app: fluentd-logging
version: v1
template:
metadata:
labels:
k8s-app: fluentd-logging
version: v1
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch
env:
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
#- name: FLUENT_ELASTICSEARCH_HOST
# value: "xx.xx.xx.xxx"
#- name: FLUENT_ELASTICSEARCH_PORT
# value: "xxxxx"
#- name: FLUENT_ELASTICSEARCH_SCHEME
# value: "http"
# Option to configure elasticsearch plugin with self signed certs
# ================================================================
- name: FLUENT_ELASTICSEARCH_SSL_VERIFY
value: "true"
# Option to configure elasticsearch plugin with tls
# ================================================================
- name: FLUENT_ELASTICSEARCH_SSL_VERSION
value: "TLSv1_2"
# X-Pack Authentication
# =====================
- name: FLUENT_ELASTICSEARCH_USER
value: "elastic"
- name: FLUENT_ELASTICSEARCH_PASSWORD
value: "changeme"
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: dockercontainerlogdirectory2
mountPath: /var/lib/docker/containers
readOnly: true
# When actual pod logs in /var/log/pods, the following lines should be used.
- name: dockercontainerlogdirectory
mountPath: /var/log/pods
readOnly: true
- name: config
mountPath: /fluentd/etc/fluent.conf
subPath: fluent.conf
- name: config
mountPath: /fluentd/etc/index_template.json
subPath: index_template.json
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
# When actual pod logs in /var/lib/docker/containers, the following lines should be used.
# - name: dockercontainerlogdirectory
# hostPath:
# path: /var/lib/docker/containers
# When actual pod logs in /var/log/pods, the following lines should be used.
- name: dockercontainerlogdirectory
hostPath:
path: /var/log/pods
- name: dockercontainerlogdirectory2
hostPath:
path: /var/lib/docker/containers
- name: config
configMap:
name: fluentd-config
입력이 필요한 부분은 ConfigMap
에서 환경변수로 표시해두었으니 추가해주도록 하자. ex) ${ELASTICSEARCH_HOST_IP}
, ${ELASTICSEARCH_HOST_REST_PORT}
위 deamonset을 만든다음에 3분마다 kibana
의 index management
tab에 가서 rollover되고 오래된 데이터는 삭제되는지 확인해주도록 하자. 단, elasticsearch
의 ILM
poll은 default가 10분이다. 따라서, 결과를 바로바로 확인하고 싶다면 다음과 같이 poll_interval
을 10초로 바꿀 수 있다.
PUT /_cluster/settings
{
"transient" : {
"indices.lifecycle.poll_interval" : "10s"
}
}
필자는 ${LOGSTASH_INDEX_PREFIX}
에 park
이라는 index
를 만들었고, fluentd에서 다음과 같이 자동으로 다음과 같이 만들어지는 것을 볼 수 있다.
GET _cat/indices
...
yellow open park--2023.12.08-000001 GV-NrXxuQsW9L-z3j5n3HQ 1 1 233 0 98.2kb 98.2kb
...
참고로, elasticsearch plugin에 application_name
을 설정하면 park-${application_name}-2023.12.08
이 된다. 필자는 application_name: ""
으로 설정해서 park--2023.12.08
이 된 것이다.
park
만 주었는데도, ilm
과 template
덕분에 park--{날짜}-000001
이라는 index가 나오는 것이다. 다음으로 _alias
를 확인해보도록 하자.
GET park--2023.12.08-000001
{
"park--2023.12.08-000001" : {
"aliases" : {
"park-2023.12.08" : {
"is_write_index" : true
}
},
...
"settings" : {
"index" : {
"lifecycle" : {
"name" : "retention-3m",
"rollover_alias" : "park-2023.12.08"
},
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1",
"provided_name" : "<park--2023.12.08-000001>",
"creation_date" : "1702001064437",
"number_of_replicas" : "1",
"uuid" : "GV-NrXxuQsW9L-z3j5n3HQ",
"version" : {
"created" : "7171499"
}
}
}
}
}
index park--2023.12.08-000001
에 park-2023.12.08
이라는 alias
가 자동으로 할당된 것을 볼 수 있다. rollover_alias
도 park-2023.12.08
로 잘 붙어있는 것을 볼 수 있다. 그렇다면 park--2023.12.08-000001
에는 index-template
와 ilm
이 잘 붙어있는 지 확인해보도록 하자.
GET park--2023.12.08-000001/_ilm/explain
응답으로 다음이 나온다.
{
"indices" : {
"park--2023.12.08-000001" : {
"index" : "park--2023.12.08-000001",
"managed" : true,
"policy" : "retention-3m",
"lifecycle_date_millis" : 1702001064437,
"age" : "6m",
"phase" : "hot",
"phase_time_millis" : 1702001064512,
"action" : "rollover",
"action_time_millis" : 1702001064512,
"step" : "check-rollover-ready",
"step_time_millis" : 1702001064512,
"phase_execution" : {
"policy" : "retention-3m",
"phase_definition" : {
"min_age" : "0ms",
"actions" : {
"rollover" : {
"max_size" : "5gb",
"max_age" : "3m"
}
}
},
"version" : 1,
"modified_date_in_millis" : 1702001064488
}
}
}
}
retention-3m
ILM이 잘 걸린 것이 확인된다.
마지막으로 index-template를 확인하여, rollover_alias
가 park--2023.12.08-000001
index의 alias
인 park-2023.12.08
과 동일한 지 확인해야한다. index-template의 이름은 kibana
에서 index management
-> index template
칸으로 가면 park-2023.12.08
라는 index template가 만들어진 것을 볼 수 있다.
GET _template/park-2023.12.08
...
{
"park-2023.12.08" : {
"order" : 53,
"index_patterns" : [
"park--2023.12.08-*"
],
"settings" : {
"index" : {
"lifecycle" : {
"name" : "retention-3m",
"rollover_alias" : "park-2023.12.08"
},
"number_of_replicas" : "1"
}
},
"mappings" : { },
"aliases" : { }
}
}
park-2023.12.08
index-template가 index pattern으로 fluentd에서 data를 쏘고 있는 index로 보내고 있는 것을 확인할 수 있고, licycle
부분에 ILM로 retention-3m
이 연결된 것을 볼 수 있다. 마지막으로 rollover_alias
가 park-2023.12.08
으로, park--2023.12.08-000001
index의 rollover alias와 동일한 것을 확인할 수 있다.
이제 rollover가 성립되는 조건은 모두 만족하였다. 실제로 rollover가 되는 지 안되는 지 확인해보도록 하자. 필자의 경우 3분 후에 rollover되고 3분 후에 rollover된 index를 삭제하도록 하였다. 실제로 시간이 지나면 다음과 같이 index가 만들어진다.
park--2023.12.08-000001
park--2023.12.08-000002
park--2023.12.08-000001
이 rollover되고 park--2023.12.08-000002
에 새로운 데이터가 쓰이고 있을 것이다. 확인해보도록하자.
GET park--2023.12.08-000001
{
"park--2023.12.08-000001" : {
"aliases" : {
"park-2023.12.08" : {
"is_write_index" : false
}
},
...}
}
alias
인 park-2023.12.08
의 is_write_index
부분이 false
인 것을 확인할 수 있다. 해당 index에 write되고 있는 data가 없다는 것이다. 반면에 park--2023.12.08-000002
를 확인하면 log가 들어오고 있기 때문에 is_write_index
는 true
가 된다.
GET park--2023.12.08-000002
{
"park--2023.12.08-000002" : {
"aliases" : {
"park-2023.12.08" : {
"is_write_index" : true
}
},
...}
}
시간이 왕창 지나면 다음과 같이 이전에 rollover된 index들은 사라지게 된다.
park--2023.12.08-000010
park--2023.12.08-000011
park--2023.12.08-000012
참고로, 다음의 기능은 날짜가 바뀌면 다음과 같이 날짜가 바뀌는대로 새로운 index-template를 만들고 index를 rollover한다.
park--2023.12.09-000023
park--2023.12.09-000024
park--2023.12.09-000025
index-template
로 park-2023.12.09
가 만들어지고 alias
는 park-2023.12.09
가 된다.
이것으로 fluentd에 대한 내용은 끝이다. 그 밖에 plugin들에 대한 내용은 일부 다룰 수는 있겠지만, docs를 참고하는 편이 좋으며 직접하는 것을 추천한다.