데이터 쿼리 시 정규식 사용
IBM Cloud Logs 데이터를 조회할 때 정규 표현식(regex)을 사용하여 패턴 검색 및 문자열 치환을 수행할 수 있습니다.
분석과 시각화를 쉽게 하기 위해 로그에서 특정 데이터를 추출할 수 있습니다. 때로는 특정 로그 데이터를 캡처하고 싶을 때가 있습니다. 또 다른 경우에는 로그에 민감한 데이터를 저장하기 전에 숨겨야 할 수도 있습니다.
정확한 텍스트 검색 대신 정규식 패턴을 사용하여 일치시킬 수도 있습니다.
정규 표현식(regex)이란 무엇이며, 어떻게 작동하나요?
정규식(regex)은 패턴 검색 및 대체를 위해 사용되는 도메인 특정 언어(DSL)입니다.
이 주제의 정보는 정규 표현식에 대한 완전한 교육용 튜토리얼을 제공하기 위한 것이 아닙니다. 정규 표현식에 익숙하지 않다면, 여기에 포함된 구체적인 개념을 이해하기 전에 공개적으로 이용 가능한 정규 표현식에 대한 정보를 검토해 보는 것이 좋습니다.
정규식 개념
이 주제의 예제를 이해하기 위해 알아야 할 몇 가지 기본 개념이 있습니다.
- 캡처 그룹
- 괄호 안에 정규식 포함. 연산자는 괄호 안에 있는 사양과 일치하는 텍스트에 적용됩니다.
- 이름이 지정된 캡처 그룹
- 이름과 관련된 캡처 그룹입니다. 일치된 결과는 이름으로 참조할 수 있습니다
- 문자 클래스
- 일치시킬 문자 범위는 대괄호(
[])로 묶습니다. 여러 문자를 나열할 때는 대시를 사용하여 줄일 수 있습니다.[1-5]는[12345]와 같습니다.
정규 표현식을 사용할 때
정규 표현식이 필요하지 않은 경우도 있고, 특정 텍스트를 검색할 수 있는 경우도 있습니다. 예를 들어, 로그에 user logged in 라는 텍스트가 있는 줄을 찾으려면, 로그 검색에 이 텍스트를 입력하기만 하면 됩니다. 그러나 로그 라인이 다음과 같이 표시되는 경우: user_32 logged in 사용자 ID가 변수이므로 정확한 텍스트를 검색할 수 없습니다.
다행히도 이 경우를 위한 정규식 패턴이 있는데, 이 패턴은 임의의 시퀀스를 활용합니다:
user_d+ logged in
정규 표현식을 사용하여 텍스트를 사용자 정의 JSON 필드로 추출하기
다음과 같은 형식의 구조화되지 않은 로그를 가지고 있다고 가정해 보십시오
${logLevel}: World-${worldName}: ${logText}
그리고 이 형식의 모든 항목을 다음 형식의 JSON 객체로 변환하고 싶습니다
{
"level": `${log-level}`,
"tag": `World-${worldName}`,
"text": `${logText}`
}
이 정규 표현식을 사용하여 변환할 수 있습니다
^(?P.*?):s*(?P.*?):
여기서:
^는 줄 시작 기호입니다. 이것은 경기가 줄의 시작과 함께 시작되어야 한다는 것을 의미합니다.(?PX)X는 일치하는 부분이고, 명명된 캡처 그룹 구문입니다. 이 정규 표현식은 필요한 JSON 키마다 하나씩, 총 세 개의 캡처 그룹을 가지고 있습니다.s"공백 문자"를 의미합니다..“어떤 한 글자”를 의미합니다.*"이전 기호 또는 문자와 일치하는 0개 이상의 문자"를 의미합니다..*"이전 기호 또는 문자가 1회 이상 일치하는 것"을 의미합니다..*?"최소한의 토큰으로 원하는 만큼 반복해서 입력할 수 있는 문자"를 의미합니다.
그래서 정규식:
^(?P.*?):s*(?P.*?):
다음과 같이 처리됩니다
-
줄의 시작부터 첫 번째
:기호까지 텍스트가 그룹level로 캡처됩니다. -
공백이 여러 개 있는 경우, 다음
:기호까지 모든 텍스트가tag그룹으로 캡처됩니다. -
IBM Cloud Logs 에 의해 로그 텍스트가 자동으로 "
text" 필드로 설정되므로, "text" 필드가 자동으로 생깁니다.
동일한 정규표현식을 사용하여 다음 로그를 확인합니다
"info: World-w-8: generate: new world"
다음과 같은 JSON 객체로 변환됩니다:
{
"level": "info",
"tag": "World-w-8",
"text": "info: World-w-8: generate: new world"
}
텍스트를 미리 정의된 필드로 추출
텍스트를 미리 정의된 필드로 추출할 수 있습니다. 이 로그를 고려해 보세요:
"info: World-w-8: generate: new world"
info 텍스트를 Severity 열로 추출하고, World 텍스트를 Class 열로 추출할 수 있습니다.
다음과 같이 정규 표현식을 수정하여 캡처 그룹의 이름을 올바르게 설정할 수 있습니다
^(?P.*?):s*(?P.*?)-(?P.*?):
이 정규 표현식은 로그를 다음과 같이 표시되도록 포맷합니다.
구조화된 로그에서 특정 데이터 추출하기
유사한 방법을 사용하여 구조화된 로그에서 데이터를 추출할 수 있습니다. 다음은 특정 JSON 필드에서 데이터를 추출하는 방법을 보여주는 예제입니다.
다음과 같은 구조화된 로그 라인이 있다고 가정해 보겠습니다
{
"type": `${text}`,
"log": `${text}`,
"region": "rg-europe-2"
}
region 필드가 다음과 같은 형식이라면:
`rg-${"europe"|"asia"|"na"}-${number}`
europe, asia, na 중 어느 지역인지 알려주는 부분을 추출하고자 합니다. 데이터를 추출하는 정규식은 다음과 같습니다
"region"s*:s*"rg-(?P.*?)-
이름이 지정된 캡처 그룹인 regionName 이 텍스트를 추출합니다. 지역 이름은 키 이름인 region 와 문자를 따서 붙인 것입니다. rg- 는 저희 형식에 따릅니다. s* 기호의 목적은 정규 표현식이 : 기호 앞뒤에 공백이 있는 경우에도 여전히 작동하도록 하는 것입니다.
결과는 다음과 비슷할 것입니다:
{
"log" : "Bye",
"regionName" : "na",
"region" : "rg-na-1",
"type" : "ltest-w-9"
}
값 바꾸기 및 제거
가장 흔한 예로, 개인 정보를 숨기는 경우를 들 수 있습니다. 전화번호를 어딘가에 기록해 두었는데, IBM Cloud Logs 에 저장되는 것을 원하지 않는다고 가정해 보십시오.
다음과 같은 구조화되지 않은 로그 라인이 있다고 가정해 보겠습니다
"info: Sender: sendSms: sending sms to phone number +12345678910 to user Andrew"
이 줄에서 전화번호와 이름을 제거하고 싶습니다. 이 정규식은 "sending sms"로 시작하는 줄과 일치합니다
sending sms to phone number +*d+ to user .*
+ + 기호는 공백으로 처리해야 합니다. 왜냐하면 정규식 구문에서 는 특별한 의미를 갖기 때문입니다. 이 의미는 "이전의 문자 1개 이상"입니다.
d 기호는 모든 단일 숫자와 일치합니다. * 기호는 "0 또는 그 이상의 이전 문자"를 의미한다는 것을 기억하십시오. 따라서, +*d+는 + 기호(또는 그 기호 없이)로 시작할 수 있는 하나 이상의 숫자와 일치합니다.
이 정규식은 이전 정규식과 일치하는 텍스트를 같은 텍스트로 대체하지만, 전화번호와 이름은 제외합니다
sending sms to phone number * to user *
그리고 위의 규칙을 적용한 결과는 다음과 같습니다
"info: Sender: sendSms: sending sms to phone number * to user *"
구조화된 로그에서 JSON 값 교체
구조화된 로그에서 JSON 값을 바꾸는 것은 비구조화된 로그에서 값을 바꾸는 것과 비슷합니다. 전체 JSON 문자열이 Replace 규칙의 입력으로 사용됩니다.
다음과 같은 JSON 구조를 사용합니다:
{
"type": `${text}`,
"log": `${text}`,
"region": "rg-europe-2"
}
type 필드의 값을 다른 값으로 바꾸어야 한다고 가정해 보십시오. type 필드의 값을 일치시키는 방법은 다음과 같습니다
"type"s*:s*".*?"
공백이 : 문자 앞이나 뒤에 있는 경우 정규식이 제대로 작동하도록 하려면 공백( s* ) 기호가 필요하다는 것을 기억하십시오.
type 필드의 모든 값을 newType 로 바꾸는 정규 표현식은 다음과 같습니다
"type":"newType"
역참조 사용하기
west-europe-2 형식의 문자열에서 europe 를 eu 로 바꿔야 한다고 가정해 보겠습니다. region 필드뿐만 아니라 문자열이 발견되는 로그의 다른 부분에서도 이 작업을 수행해야 한다고 가정해 보겠습니다. 이 패턴에 맞는 검색은 이 정규 표현식을 사용하면 쉽게 할 수 있습니다
.+?-europe-d+
그러나 이전에 사용했던 방법을 사용하여 문자열을 바꾸는 것은 다소 어려울 수 있습니다. europe 라는 텍스트의 앞뒤에 두 개의 문자열을 삽입해야 하는데, 이 문자열이 달라질 수 있기 때문입니다. 이를 위해서는 먼저 문자열을 캡처 그룹으로 캡처해야 합니다
(.+?)-europe-(d+)
d 기호는 "임의의 숫자"를 의미하며, + 기호와 함께 사용하면 "임의의 숫자가 한 번 이상"이라는 의미를 갖습니다. 이와 비슷한 방식으로, .+ 는 어떤 기호를 한 번 이상 의미하지만, 일치하는 기호를 만드는 데 필요한 토큰의 양이 가장 적습니다.
이 정규식은 europe 앞의 텍스트를 캡처 그룹 1로, europe 뒤의 텍스트를 캡처 그룹 2로 캡처합니다. 다음의 정규 표현식은 역참조(backreference)를 사용하여 해당 그룹의 일치하는 내용을 삽입합니다:
$1-eu-$2
예를 들어, 규칙을 적용하기 전의 로그:
{
"log" : "Here region is east-europe-1. That's it",
"type" : "newType",
"region" : "east-europe-1"
}
그리고 규칙을 적용한 후의 로그:
{
"log" : "Here region is east-eu-1. That's it",
"type" : "newType",
"region" : "east-eu-1"
}
로그 검색창에서 정규표현식을 사용한 검색
정규 표현식을 사용할 수 있는 또 다른 곳은 " IBM Cloud Logs "의 UI 로그 페이지 검색창입니다.
페이지 검색창에서 검색할 때는 정확한 텍스트, Lucene 또는 Dataprime 쿼리를 입력할 수 있습니다. 정규 표현식을 사용하여 특정 패턴을 찾을 수도 있습니다. 정규식 쿼리에는 다음과 같은 고유한 형식이 있습니다
/${fieldName}.keyword:/REGEX//
다음과 같은 형식의 JSON 구조의 로그를 많이 가지고 있다고 가정해 보겠습니다
{
"log": `${text}` ,
"regionName": `${text}`,
"region": `${text}`,
"type" : `ltest-w-${number}`
}
그리고 우리는 type 가 ltest-w-1, ltest-w-2 또는 ltest-w-3 와 같은 항목만 일치시키고 싶습니다. 다음 검색 쿼리를 사용하면 됩니다:
/type.keyword:/ltest-w-[1-3]//
대괄호( [ )와 중괄호( ] ) 사이에 있는 텍스트를 문자 클래스 라고 합니다. 대괄호 안에 나열된 어떤 한 글자와도 일치합니다. 대시는 여러 문자를 나열할 때 사용하는 약어입니다: [1-5] 는 [12345] 와 같습니다.
동일한 구문을 사용하여 정규 표현식과 일치하는 구조화되지 않은 로그에 있는 데이터를 사용할 수 있습니다. 필드 이름을 text.keyword 로 설정하기만 하면 됩니다. 예를 들어, 다음과 같습니다.
/text.keyword:/.*ltest-w-[1-3].*//
이 정규식은 메인 로그 본문에서 ltest-w-1, ltest-w-2 또는 ltest-w-3 텍스트를 검색합니다.
정규 표현식을 이용한 알림 트리거
IBM Cloud Logs 에서 정규 표현식을 사용하는 또 다른 인기 있는 사용 사례는 알림을 정의하는 것입니다. 알림 구문은 로그 쿼리 구문과 동일합니다.
다음과 같은 형식의 줄에 대해 알림을 받고 싶다고 가정해 봅시다
`App: init: World-${name}: generation error: ${err}`
그리고 세계 w-1, w-2, w-3 또는 w-4 에 대한 알림만 받고 싶다고 가정해 봅시다. 알림 정규표현식은 다음과 같이 표시됩니다:
/text.keyword:/.*World-w-[1-4]: generation error.*//
[1-4] 는 1 에서 4 까지 모든 단일 문자와 일치하고, .* 는 모든 문자와 여러 번 일치한다는 것을 기억하십시오.
알림에 대한 자세한 정보는 다음을 참조하십시오: