- Elasticsearch에 저장된 데이터 확인하기2024년 12월 19일
- 31514
- 작성자
- 2024.12.19.:24
샘플 로그 파일이 kibana에서 시각화되기까지의 과정은 위의 그림과 같습니다.
- logstash가 로그 파일을 읽고 필터링을 거친 다음, elasticsearch에 저장
- kibana는 elasticsearch에 저장된 데이터를 바탕으로 시각화
실제로 elasticsearch에 저장된 데이터를 확인하기 위해 kibana의 Dev Tools Console에서 다음 쿼리를 실행했습니다.
GET logstash-*/_search { "query": { "match_all": {} }, "size": 10 }
그 결과, 크게 2가지 유형의 데이터가 나온 것을 확인할 수 있었습니다.
<첫 번째 유형>
{ "_index": "logstash-2024.12.18", "_id": "_WPQ3JMBJySkpvXRWzOU", "_score": 1, "_source": { "log_message": "Begin connection : 172.75.1.105:2004", "timestamp": "2024-12-18 09:17:32.973", "log": { "file": { "path": "/usr/share/logstash/ingest_data/tsI/20241218.log" } }, "method": "BeginConnect", "@timestamp": "2024-12-18T00:17:32.973Z", "event": { "original": "[2024-12-18 09:17:32.973]::[Comm]::[ClientSocketBase.cs]::[BeginConnect]::[153]::Begin connection : 172.75.1.105:2004" }, "host": { "name": "1f544ba933f5" }, "log_level": "Comm", "@version": "1", "source_file": "ClientSocketBase.cs", "line": "153" } }
이 데이터는 실제 로그 파일에 있는 데이터입니다.
한 가지 주의할 점은 원래 `@timestamp`는 로그 발생 시각이 아니라, 데이터가 처리된 시간(logstash가 ES에 데이터를 적재한 시간)을 가리키는데, 아래와 같은 코드를 사용하면 `@timestamp`를 로그 발생 시각으로 덮어쓸 수 있습니다.
date { match => [ "timestamp", "yyyy-MM-dd HH:mm:ss.SSS" ] timezone => "Asia/Seoul" target => "@timestamp" }
그리고 `timestamp`와 `@timestamp`의 값이 다른 이유는 각각 KST, UTC이기 때문입니다.
사실 꼭 `@timestamp`의 값을 덮어쓸 필요는 없고, 서로 다른 장단점이 존재합니다.
- 덮어쓴 경우: 스토리지 절약, 단순화, 일관성, 메타데이터 손실 등
- 덮어쓰지 않은 경우: 원본 로그와 메타데이터 분리, 유연한 분석, 스토리지 사용량 증가 등
<두 번째 유형>
{ "_index": "logstash-2024.12.19", "_id": "s2HQ3JMBJySkpvXRRbgu", "_score": 1, "_source": { "tags": [ "_grokparsefailure" ], "@timestamp": "2024-12-19T02:47:35.492332337Z", "event": { "original": " 위치: System.IO.File.InternalAppendAllText(String path, String contents, Encoding encoding)" }, "host": { "name": "1f544ba933f5" }, "@version": "1", "log": { "file": { "path": "/usr/share/logstash/ingest_data/hs/20241217.log" } } } }
`tags` 키의 값을 보면 `_grokparsefailure`라는 값을 볼 수 있는데, 이는 grok 필터가 실패했을 때를 말합니다. 즉, " 위치: System.IO.File.InternalAppendAllText(String path, String contents, Encoding encoding)"데이터가 제가 지정한 `grok` 필터와 맞지 않아서 발생한 문제입니다. 왜 이런 문제가 발생했을까요? 원본 로그 파일을 살펴보니 원인을 찾을 수 있었습니다.
[2024-12-17 09:35:04.592]::[Error]::[TaskQueue.cs]::[TaskProc]::[205]::'C:\IISYS_OHLHS\Log\20241217_kp.csv' 파일은 다른 프로세스에서 사용 중이므로 프로세스에서 액세스할 수 없습니다. [2024-12-17 09:35:04.598]::[Debug]::[TaskQueue.cs]::[TaskProc]::[205]:: 위치: System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 위치: System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
이를 해결하기 위해 logstash.conf 파일의 `input` 섹션 부분에 `multiline` 옵션과 정규표현식을 사용하여 여러 줄로 구성되어 있는 로그 데이터도 인식할 수 있도록 하였습니다.
input { file { mode => "read" path => "/usr/share/logstash/ingest_data/**/*.log" exit_after_read => true file_completed_action => "log" file_completed_log_path => "/usr/share/logstash/ingest_data/logstash_completed.log" start_position => "beginning" sincedb_path => "/dev/null" codec => multiline { pattern => "^\[\d{4}-\d{2}-\d{2}.*$" negate => true what => "previous" } } }
그 결과 Elasticsearch에 저장된 데이터의 예시는 다음과 같습니다.
{ "_index": "logstash-2024.12.17", "_id": "4suB3ZMBk44LdPIjwEKW", "_score": 1, "_ignored": [ "log_message.keyword", "event.original.keyword" ], "_source": { "tags": [ "multiline" ], "event": { "original": """[2024-12-17 12:21:35.714]::[Debug]::[TaskQueue.cs]::[TaskProc]::[205]:: 위치: System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 위치: System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost) 위치: System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost) 위치: System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding) 위치: System.IO.File.InternalAppendAllText(String path, String contents, Encoding encoding) 위치: IISYS.Inspection.ServiceProvider.OHLHS.OHLHSSystemService.OnInspectionResultsCallback(IEnumerable`1 inspectResults) 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Application\IISYS.Inspector\IISYS.Inspection\ServiceProvider\OHLHS\OHLHSSystemService.cs:줄 116 위치: IISYS.Inspection.Tasks.ProfilerQueueTaskBase.MultiObjectProc(List`1 dataList) 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Application\IISYS.Inspector\IISYS.Inspection\Tasks\ProfilerQueueTaskBase.cs:줄 122 위치: Utility.Tasks.TaskQueue`1.TaskProc() 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Common\Utility\Tasks\TaskQueue.cs:줄 188 """ }, "@version": "1", "log": { "file": { "path": "/usr/share/logstash/ingest_data/hs/20241217.log" } }, "line": "205", "method": "TaskProc", "log_message": """ 위치: System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 위치: System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 위치: System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost) 위치: System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost) 위치: System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding) 위치: System.IO.File.InternalAppendAllText(String path, String contents, Encoding encoding) 위치: IISYS.Inspection.ServiceProvider.OHLHS.OHLHSSystemService.OnInspectionResultsCallback(IEnumerable`1 inspectResults) 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Application\IISYS.Inspector\IISYS.Inspection\ServiceProvider\OHLHS\OHLHSSystemService.cs:줄 116 위치: IISYS.Inspection.Tasks.ProfilerQueueTaskBase.MultiObjectProc(List`1 dataList) 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Application\IISYS.Inspector\IISYS.Inspection\Tasks\ProfilerQueueTaskBase.cs:줄 122 위치: Utility.Tasks.TaskQueue`1.TaskProc() 파일 C:\WorkSpace\IISYS.inspector_OHLHS\Common\Utility\Tasks\TaskQueue.cs:줄 188 """, "timestamp": "2024-12-17 12:21:35.714", "@timestamp": "2024-12-17T03:21:35.714Z", "host": { "name": "0998624e8f3b" }, "log_level": "Debug", "source_file": "TaskQueue.cs" } }
'ELK' 카테고리의 다른 글
새로운 로그를 위해 Filebeat 도입하기 (0) 2024.12.20 샘플 로그 파일 업로드하기 (0) 2024.12.19 Elastic Stack 실행하고 확인하기 (0) 2024.12.19 Elastic 공식 문서로 살펴보는 docker-compose 파일 (0) 2024.12.18 다음글이전글이전 글이 없습니다.댓글