From a0496b0f40c37b9a5c4747a58f34dbd47a27f1ed Mon Sep 17 00:00:00 2001 From: ac2550 Date: Thu, 20 Sep 2018 14:57:22 +0200 Subject: Migrate ELK to 6.1.3 OSS + add logstash configuration for a 2nd aggregated index + use new restore scripts for restoring dashboards Change-Id: I9176fa3b551591fdaf968e5b2496d510581aca22 Issue-ID: CLAMP-222 Signed-off-by: ac2550 --- .../clamp-dash-logstash/resources/certs/aafca.pem | 26 +++ .../resources/config/logstash.yml | 2 +- .../resources/config/pipeline.conf | 220 +++++++++++++++------ 3 files changed, 191 insertions(+), 57 deletions(-) create mode 100644 kubernetes/clamp/charts/clamp-dash-logstash/resources/certs/aafca.pem (limited to 'kubernetes/clamp/charts/clamp-dash-logstash/resources') diff --git a/kubernetes/clamp/charts/clamp-dash-logstash/resources/certs/aafca.pem b/kubernetes/clamp/charts/clamp-dash-logstash/resources/certs/aafca.pem new file mode 100644 index 0000000000..cf12ec4c61 --- /dev/null +++ b/kubernetes/clamp/charts/clamp-dash-logstash/resources/certs/aafca.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEVDCCAjygAwIBAgIBAjANBgkqhkiG9w0BAQsFADAsMQ4wDAYDVQQLDAVPU0FB +RjENMAsGA1UECgwET05BUDELMAkGA1UEBhMCVVMwHhcNMTgwNjA1MDg1MTQxWhcN +MjMwNjA1MDg1MTQxWjBHMQswCQYDVQQGEwJVUzENMAsGA1UECgwET05BUDEOMAwG +A1UECwwFT1NBQUYxGTAXBgNVBAMMEGludGVybWVkaWF0ZUNBXzEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOXCdZIoWM0EnEEw3qPiVMhAgNolWCTaLt +eI2TjlTQdGDIcXdBZukHdNeOKYzOXRsLt6bLRtd5yARpn53EbzS/dgAyHuaz1HjE +5IPWSFRg9SulfHUmcS+GBt1+KiMJTlOsw6wSA73H/PjjXBbWs/uRJTnaNmV3so7W +DhNW6fHOrbom4p+3FucbB/QAM9b/3l/1LKnRgdXx9tekDnaKN5u3HVBmyOlRhaRp +tscLUCT3jijoGAPRcYZybgrpa0z3iCWquibTO/eLwuO/Dn7yHWau9ZZAHGPBSn9f +TiLKRYV55mNjr3zvs8diTPECFPW8w8sRIH3za1aKHgUC1gd87Yr3AgMBAAGjZjBk +MB0GA1UdDgQWBBQa1FdycErTZ6nr4dxiMbKH0P7vqjAfBgNVHSMEGDAWgBRTVTPy +S+vQUbHBeJrBKDF77+rtSTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAlA/RTPy5i09fJ4ytSAmAdytMwEwRaU9F +dshG7LU9q95ODsuM79yJvV9+ISIJZRsBqf5PDv93bUCKKHIYGvR6kNd+n3yx/fce +txDkC/tMj1T9D8TuDKAclGEO9K5+1roOQQFxr4SE6XKb/wjn8OMrCoJ75S0F3htF +LKL85T77JeGeNgSk8JEsZvQvj32m0gv9rxi5jM/Zi5E2vxrBR9T1v3kVvlt6+PSF +BoHXROk5HQmdHxnH+VYQtDHSwj9Xe9aoJMyL0WjYKd//8NUO+VACDOtK4Nia6gy9 +m/n9kMASMw6f9iF4n6t4902RWrRKTYM1CVu5wyVklVbEdE9i6Db4CpL9E8HpBUAP +t44JiNzuFkDmSE/z5XuQIimDt6nzOaSF8pX2KHY2ICDLwpMNUvxzqXD9ECbdspiy +JC2RGq8uARGGl6kQQBKDNO8SrO7rSBPANd1+LgqrKbCrHYfvFgkZPgT5MlQi+E1G +LNT+i6fzZha9ed/L6yjl5Em71flJGFwRZl2pfErZRxp8pLPcznYyIpSjcwnqNCRC +orhlp8nheiODC3oO3AFHDiFgUqvm8hgpnT2cPk2lpU2VY1TcZ8sW5qUDCxINIPcW +u1SAsa87IJK3vEzPZfTCs/S6XThoqRfXj0c0Rahj7YFRi/PqIPY0ejwdtmZ9m9pZ +8Lb0GYmlo44= +-----END CERTIFICATE----- diff --git a/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/logstash.yml b/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/logstash.yml index 51470d265b..369b5820d5 100644 --- a/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/logstash.yml +++ b/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/logstash.yml @@ -26,4 +26,4 @@ config.reload.automatic: true #xpack.monitoring.elasticsearch.url: ["http://10.247.186.12:9200", "http://10.247.186.13:9200"] #xpack.monitoring.elasticsearch.username: elastic #xpack.monitoring.elasticsearch.password: changeme -xpack.monitoring.enabled: false +#xpack.monitoring.enabled: false diff --git a/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/pipeline.conf b/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/pipeline.conf index f88e40da14..317b428c77 100644 --- a/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/pipeline.conf +++ b/kubernetes/clamp/charts/clamp-dash-logstash/resources/config/pipeline.conf @@ -1,4 +1,4 @@ -# Copyright © 2018 AT&T, Amdocs, Bell Canada Intellectual Property. All rights reserved. +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. input { - http_poller { + http_poller { urls => { event_queue => { method => get @@ -20,8 +20,8 @@ input { headers => { Accept => "application/json" } - add_field => { "topic" => "${event_topic}" } - type => "dmaap_event" + topic => "${event_topic}" + tags => [ "dmaap_source" ] } notification_queue => { method => get @@ -29,8 +29,8 @@ input { headers => { Accept => "application/json" } - add_field => { "topic" => "${notification_topic}" } - type => "dmaap_notification" + topic => "${notification_topic}" + tags => [ "dmaap_source" ] } request_queue => { method => get @@ -38,66 +38,91 @@ input { headers => { Accept => "application/json" } - add_field => { "topic" => "${request_topic}" } - type => "dmaap_request" + topic => "${request_topic}" + tags => [ "dmaap_source" ] } } socket_timeout => 30 request_timeout => 30 - interval => 60 + schedule => { "every" => "1m" } codec => "plain" - } + cacert => "/certs.d/aafca.pem" + } } + filter { - if [type] != "dmaap_log" { - # avoid noise if no entry in the list - if [message] == "[]" { - drop { } - } + # avoid noise if no entry in the list + if [message] == "[]" { + drop { } + } + + if [http_request_failure] or [@metadata][code] != "200" { + mutate { + add_tag => [ "error" ] + } + } - # parse json, split the list into multiple events, and parse each event + if "dmaap_source" in [tags] { + # + # Dmaap provides a json list, whose items are Strings containing the event + # provided to Dmaap, which itself is an escaped json. + # + # We first need to parse the json as we have to use the plaintext as it cannot + # work with list of events, then split that list into multiple string events, + # that we then transform into json. + # json { - source => "[message]" - target => "message" + source => "[message]" + target => "message" } + ruby { + code => " + for ev in event.get('message', []) + ev.set('@metadata', event.get('@metadata')) + end + " + } + split { - field => "message" - add_field => { - "type" => "%{type}" - "topic" => "%{topic}" - } + field => "message" } json { - source => "message" + source => "message" + } + mutate { + remove_field => [ "message" ] } - mutate { remove_field => [ "message" ] } } - - # express timestamps in milliseconds instead of microseconds - ruby { + + # + # Some timestamps are expressed as milliseconds, some are in microseconds + # + if [closedLoopAlarmStart] { + ruby { code => " - if event.get('closedLoopAlarmStart').to_s.to_i(10) > 9999999999999 - event.set('closedLoopAlarmStart', event.get('closedLoopAlarmStart').to_s.to_i(10) / 1000) - else - event.set('closedLoopAlarmStart', event.get('closedLoopAlarmStart').to_s.to_i(10)) - end - " - } - date { - match => [ "closedLoopAlarmStart", UNIX_MS ] - target => "closedLoopAlarmStart" + if event.get('closedLoopAlarmStart').to_s.to_i(10) > 9999999999999 + event.set('closedLoopAlarmStart', event.get('closedLoopAlarmStart').to_s.to_i(10) / 1000) + else + event.set('closedLoopAlarmStart', event.get('closedLoopAlarmStart').to_s.to_i(10)) + end + " + } + date { + match => [ "closedLoopAlarmStart", UNIX_MS ] + target => "closedLoopAlarmStart" + } } if [closedLoopAlarmEnd] { ruby { code => " - if event.get('closedLoopAlarmEnd').to_s.to_i(10) > 9999999999999 - event.set('closedLoopAlarmEnd', event.get('closedLoopAlarmEnd').to_s.to_i(10) / 1000) - else - event.set('closedLoopAlarmEnd', event.get('closedLoopAlarmEnd').to_s.to_i(10)) - end - " + if event.get('closedLoopAlarmEnd').to_s.to_i(10) > 9999999999999 + event.set('closedLoopAlarmEnd', event.get('closedLoopAlarmEnd').to_s.to_i(10) / 1000) + else + event.set('closedLoopAlarmEnd', event.get('closedLoopAlarmEnd').to_s.to_i(10)) + end + " } date { match => [ "closedLoopAlarmEnd", UNIX_MS ] @@ -105,39 +130,122 @@ filter { } } - #"yyyy-MM-dd HH:mm:ss" + + + # + # Notification time are expressed under the form "yyyy-MM-dd HH:mm:ss", which + # is close to ISO8601, but lacks of T as spacer: "yyyy-MM-ddTHH:mm:ss" + # if [notificationTime] { - mutate { - gsub => [ - "notificationTime", " ", "T" - ] - } - date { + mutate { + gsub => [ + "notificationTime", " ", "T" + ] + } + date { match => [ "notificationTime", ISO8601 ] target => "notificationTime" - } + } + } + + + # + # Renaming some fields for readability + # + if [AAI][generic-vnf.vnf-name] { + mutate { + add_field => { "vnfName" => "%{[AAI][generic-vnf.vnf-name]}" } + } + } + if [AAI][generic-vnf.vnf-type] { + mutate { + add_field => { "vnfType" => "%{[AAI][generic-vnf.vnf-type]}" } + } + } + if [AAI][vserver.vserver-name] { + mutate { + add_field => { "vmName" => "%{[AAI][vserver.vserver-name]}" } + } + } + if [AAI][complex.city] { + mutate { + add_field => { "locationCity" => "%{[AAI][complex.city]}" } + } + } + if [AAI][complex.state] { + mutate { + add_field => { "locationState" => "%{[AAI][complex.state]}" } + } + } + + + # + # Adding some flags to ease aggregation + # + if [closedLoopEventStatus] =~ /(?i)ABATED/ { + mutate { + add_field => { "flagAbated" => "1" } + } + } + if [notification] =~ /^.*?(?:\b|_)FINAL(?:\b|_).*?(?:\b|_)FAILURE(?:\b|_).*?$/ { + mutate { + add_field => { "flagFinalFailure" => "1" } + } + } + + + if "error" not in [tags] { + # + # Creating data for a secondary index + # + clone { + clones => [ "event-cl-aggs" ] + add_tag => [ "event-cl-aggs" ] + } + + if "event-cl-aggs" in [tags] { + # + # we only need a few fields for aggregations; remove all fields from clone except : + # vmName,vnfName,vnfType,requestID,closedLoopAlarmStart, closedLoopControlName,closedLoopAlarmEnd,abated,nbrDmaapevents,finalFailure + # + prune { + whitelist_names => ["^@.*$","^topic$","^type$","^tags$","^flagFinalFailure$","^flagAbated$","^locationState$","^locationCity$","^vmName$","^vnfName$","^vnfType$","^requestID$","^closedLoopAlarmStart$","^closedLoopControlName$","^closedLoopAlarmEnd$","^target$","^target_type$","^triggerSourceName$","^policyScope$","^policyName$","^policyVersion$"] + } + + } } } + + output { stdout { codec => rubydebug } - if [http_request_failure] { + if "error" in [tags] { elasticsearch { codec => "json" hosts => ["${elasticsearch_base_url}"] index => "errors-%{+YYYY.MM.DD}" doc_as_upsert => true } - } else { + + } else if "event-cl-aggs" in [tags] { elasticsearch { codec => "json" hosts => ["${elasticsearch_base_url}"] - index => "logstash-%{+YYYY.MM.DD}" # creates daily indexes + document_id => "%{requestID}" + index => "events-cl-%{+YYYY.MM.DD}" # creates daily indexes for control loop doc_as_upsert => true + action => "update" + } + } else { + elasticsearch { + codec => "json" + hosts => ["${elasticsearch_base_url}"] + index => "events-%{+YYYY.MM.DD}" # creates daily indexes + doc_as_upsert => true } } - } -- cgit 1.2.3-korg