-
Logstash에서 날짜, 시간 데이터 변경하기소프트웨어개발 이야기 2020. 2. 11. 14:41
Elastic Stack을 사용하여 시청률 데이터를 분석하는 간단한 분석서비스를 만들고 있다.
S3에 올라간 일간 시청률 파일을 Logstash에서 읽고 ElasticSearch에 인덱싱해서 Kibana로 보여주는 정말 간단한 환경이다. 문제는 Kibana 시각화를 위해 시청률 파일에서 프로그램 시작 시간과 종료 시간을 Datetime 형식으로 전환해야 하는데 Logstash를 처음 사용하다 보니 삽질의 연속이다 -0-;(뭐.. 다 이렇게 배우는거지... 라고 위안중이다.)
해서, 오늘도 어김없이 삽질 기록서를 작성한다.
먼저 S3에서 파일을 읽어오기 위해 입력 파이프 라인에 s3필터를 사용했다.
input { s3 { access_key_id => "키 아이디" secret_access_key => "키 비밀번호" region => "ap-northeast-2" bucket => "s3-mbcrnd-nielsen" prefix => "RLD/Nielsen_PRO3_SAMPLE" codec => plain { charset => "EUC-KR" } sincedb_path => "/dev/null" interval => 120 } }
prefix를 통해 읽기 위한 시청률 데이터 파일을 선정했고, EUC-KR 파일 형식을 위해 charset 값을 설정했다. 추가로 반복적인 테스트를 위해 최근 읽은 위치를 무시하도록 sincedb_path를 "/dev/null"로 설정하고 읽는 주기를 2분으로 했다.
시청률 파일에 데이터 외에 불필요한 정보가 있어서 by pass 시키도록 filter 처리를 아래와 같이 했다.
filter { if [message] =~ "날짜" { drop { } } if [message] =~ /^[\^]{6}/ { drop { } } }
문제는 시청률 파일에서 프로그램 시작시간과 종료시간이 24시를 초과해서 아래와 같이 표시되고 있었다.
날짜^채널^프로그램 시작시간^프로그램 종료시간^제목^설명^장르소분류^시청률 2020-02-05^MBC^24:06:08^24:32:47^황금어장라디오스타^2부^오락종합(오락종합)^5.1
데이터는 외부 업체를 통해 제공되고 있기 때문에 원본 데이터를 변경할 수는 없었고, 이를 logstash에서 변경해서 인덱싱해야 했다. 즉 24시를 넘어설 경우, 날짜값을 하루 증가시키고 시간값에서 24시를 빼는 작업이 필요했다.
filter { # ... mutate { convert => { "start_time_hour" => "integer" } add_field => { "start_datetime" => "%{air_date} %{start_time_hour}:%{start_time_minute}:%{start_time_second}" } } if [start_time_hour] >= 24 { ruby { code => " temp_hour = event.get('[start_time_hour]') - 24; formatted_hour = '%02d' % [temp_hour]; event.set('start_time_hour_new', formatted_hour); " } mutate { add_field => { "start_datetime_calc" => "%{air_date} %{start_time_hour_new}:%{start_time_minute}:%{start_time_second}" } } date { match => ["start_datetime_calc", "yyyy-MM-dd HH:mm:ss"] timezone => "UTC" locale => "ko" target => "start_datetime_calc" } ruby { code => 'event.set("start_datetime_calc", LogStash::Timestamp.new(Time.at(event.get("start_datetime_calc").to_f+86400)))' } } else { date { match => ["start_datetime", "yyyy-MM-dd HH:mm:ss"] timezone => "UTC" locale => "ko" target => "start_datetime_calc" } } }
날짜 계산을 위해 해당 필드를 integer로 변환하는 작업이 필요하고, 24시간을 초과할 경우 시간에서 24를 빼고, 날짜를 하루 더하는 로직을 작성했다. ruby 필터로 보다 깔끔하게 작성 가능하지만 여기서는 다양한 필터를 활용해서 작성했다.(마..맞다 루비 API 찾는게 귀찮다;;;)
rubydebug로 출력하면, 24시를 초과하는 값과 그렇지 않은 값이 모두 정상적으로 계산되는 것을 확인할 수 있다.
{ "end_time_second" => "10", "program" => "함께사는세상희망프로젝트나누면행복", "end_datetime_calc" => 2020-02-06T01:35:10.000Z, "start_datetime_calc" => 2020-02-06T00:40:04.000Z, "end_datetime" => "2020-02-05 25:35:10", "sub_program" => "", "end_time_minute" => "35", "start_time_hour" => 24, "end_time_hour_new" => "01", "@timestamp" => 2020-02-11T05:29:56.074Z, "house_rating" => 1.0, "start_time_second" => "04", "start_time_hour_new" => "00", "start_datetime" => "2020-02-05 24:40:04", "genre" => "다큐멘터리(휴먼)", "air_date" => "2020-02-05", "end_time_hour" => 25, "start_time_minute" => "40", "channel" => "MBC", "@version" => "1" } { "end_time_second" => "44", "program" => "황금어장라디오스타", "end_datetime_calc" => 2020-02-06T00:04:44.000Z, "start_datetime_calc" => 2020-02-05T23:08:24.000Z, "end_datetime" => "2020-02-05 24:04:44", "sub_program" => "1부", "end_time_minute" => "04", "start_time_hour" => 23, "end_time_hour_new" => "00", "@timestamp" => 2020-02-11T05:29:56.073Z, "house_rating" => 5.8, "start_time_second" => "24", "start_datetime" => "2020-02-05 23:08:24", "genre" => "오락종합(오락종합)", "air_date" => "2020-02-05", "end_time_hour" => 24, "start_time_minute" => "08", "channel" => "MBC", "@version" => "1" }
'소프트웨어개발 이야기' 카테고리의 다른 글
Logstash 복수 파이프라인 파일 (0) 2020.02.12 Logstash에서 S3 input을 정상적으로 가져오지 못할때 (1) 2020.02.11 Postman 사용하기 (0) 2020.02.10 웹 서버 로그 분석도구 GoAccess (0) 2020.02.10 유튜브(Youtube) API - 7.Data API (Playlists, PlayItems) (1) 2020.02.10