Wie man

So streamen Sie Protokolle in AWS von CloudWatch zu ElasticSearch

So streamen Sie Protokolle in AWS von CloudWatch zu ElasticSearch

Der Artikel soll den Leser Schritt für Schritt durch das Streamen von Protokollen von einer CloudWatch-Protokollgruppe zu einem AWS Elasticsearch-Cluster führen. Es führt den Leser durch die Erstellung einer Lambda-Richtlinie und einer Rolle. Dann wird hervorgehoben, wie der Abonnementfilter für die elastische Suche erstellt wird. Schließlich wird dem Benutzer gezeigt, wie die Lambda-Funktion geändert werden kann, um das Streamen mehrerer Protokollgruppen zu einem Cluster zu ermöglichen.

Voraussetzungen

Vor der Ausführung der Schritte in diesem Artikel sollte der Leser haben;

Erstellen Sie die Lambda-Ausführungsrolle

Wir werden eine Lambda-Funktion verwenden, um Protokolle an Elasticsearch zu streamen. Klicken Sie in der AWS IAM-Konsole auf Richtlinien. Wählen Sie dann Richtlinie erstellen.

Richtlinie erstellen

Ein Fenster öffnet sich. Wählen Sie dann die Registerkarte JSON.

JSON-Richtlinie erstellen

Fügen Sie auf der Registerkarte JSON die folgenden Befehle ein. Stellen Sie ebenso sicher, dass Sie Ersetzen Sie die Ressource ar, mit Ihrem Elasticsearch-Cluster arn.

 "Version": "2012-10-17", "Statement": [  "Action": [ "es:*" ], "Effect": "Allow", "Resource": "arn:aws:es: eu-west-1:****************:domain/test-es-cluster/*"  ] 

Klicken Sie auf die Registerkarte Richtlinien überprüfen und geben Sie den Namen und die Beschreibung Ihrer Richtlinie ein. Klicken Sie dann auf Richtlinie erstellen. Wenn Sie fertig sind, gehen Sie immer noch in der IAM-Konsole zurück zu Rollen und klicken Sie auf Rollen erstellen.

Rolle erstellen

Servicerolle auswählen. Wählen Sie auch Lambda als Anwendungsfall.

Service und Anwendungsfall auswählen

Klicken Sie dann auf Berechtigungen und wählen Sie unter Richtlinien die Richtlinie aus, die Sie zuvor erstellt haben.

Richtlinie an Rolle anhängen

Klicken Sie auf Tags und fügen Sie die gewünschten Tags für Ihre Rolle hinzu your. Klicken Sie dann auf Review und geben Sie den Namen und die Beschreibung für die Rolle ein. Klicken Sie dann auf Rolle erstellen. Sie haben jetzt Ihre Lambda-Rolle bereit.

Vertrauensstellungen für Ihre Lambda-Rolle bearbeiten

Wählen Sie in der AWS IAM-Konsole die oben erstellte Lambda-Rolle aus. Wählen Sie dann die Registerkarte Vertrauensstellung und klicken Sie auf Vertrauensstellung bearbeiten.

Vertrauensstellung für Lambda-Rolle bearbeiten

Entfernen Sie in dem sich öffnenden Fenster alles aus dem Richtliniendokument und fügen Sie den folgenden Code ein. Klicken Sie dann auf Vertrauensrichtlinie aktualisieren.

 "Version": "2012-10-17", "Statement": [  "Effect": "Allow", "Principal":  "Service": "lambda.Amazonaws.com" , "Action": "sts:AssumeRole"  ] 

Ihre Lambda-Rolle ist jetzt bereit, Protokolle an Elasticsearch Kibana zu streamen.

Erstellen Sie ein Elasticsearch-Abonnement für Ihre Log-Gruppe

Wählen Sie in der CloudWatch-Konsole Protokollgruppen. Wählen Sie die Protokollgruppe aus, aus der Sie das Elasticsearch-Abonnement erstellen möchten. Wählen Sie im Protokollgruppenfenster Aktionen aus und wählen Sie Elasticsearch-Abonnementfilter erstellen aus dem Dropdown-Menü.

ElasticSearch-Abonnementfilter erstellen

Wählen Sie im sich öffnenden Fenster das Konto aus, in dem Ihr ES-Cluster erstellt wird. In unserem Fall befindet es sich im selben Konto wie die CloudWatch-Protokollgruppe. Wir haben „Dieses Konto“ und den Amazon ES-Cluster ausgewählt, an den wir unsere Protokolle streamen möchten. Wählen Sie dann die zuvor erstellte Lambda-Ausführungsrolle aus der Dropdown-Liste unter Lambda-Funktion Lamb.

Wählen Sie die Elasticsearch-Cluster- und Lambda-Ausführungsrolle

Wenn Sie nach unten scrollen, werden Sie aufgefordert, Ihr Protokollformat und Ihre Filter zu konfigurieren. Siehe unten.

Protokollformat und -filter konfigurieren

Wählen Sie Ihr bevorzugtes Log. Sie können auch testen und sehen, wie es aussehen wird. Wenn Sie zufrieden sind, klicken Sie auf Streaming starten. Sie sollten jetzt Ihre Logs als Indizes in der Elasticsearch Kibana . sehen.

Ändern Sie die Lambda-Funktion, um Protokolle aus mehreren Protokollgruppen zu streamen

Um Protokolle von mehreren CloudWatch-Protokollgruppen an den Elasticsearch-Cluster zu streamen, müssen wir den Code der oben erstellten ursprünglichen Lambda-Funktion ändern. Ersetzen Sie Ihren Lambda-Funktionscode durch den folgenden Code. Das einzige, was Sie am Code ändern müssen, ist der var-Endpunkt (Zeile 5 des Code-Snippets). Stellen Sie sicher, dass Sie dies durch Ihren Elasticsearch-Cluster-Endpunkt ersetzen. Wenn Sie fertig sind, klicken Sie auf Speichern.

// v1.1.2 var https = erfordern('https'); var zlib = require('zlib'); var crypto = require('crypto'); var endpoint = 'search-test-es-cluster-****************************.eu-west-1.es.Amazonaws.com'; // Setzen Sie dies auf true, wenn Sie debuggen möchten, warum Daten nicht in // Ihren Elasticsearch-Cluster gelangen. Dadurch wird die Protokollierung fehlgeschlagener Elemente // in CloudWatch Logs aktiviert. var logFailedResponses = false; Exporte.handler = function(input, context)  // Eingabe von base64 decodieren var zippedInput = new Buffer.von (Eingabe.awslogs.Daten, 'base64'); // dekomprimieren Sie die Eingabe zlib.gunzip(zippedInput, function(error, buffer)  if (error)  context.scheitern (Fehler); Rückkehr;  // die Eingabe von JSON analysieren var awslogsData = JSON.analysieren (Puffer).toString('utf8')); // die Eingabe in Elasticsearch-Dokumente umwandeln var elasticsearchBulkData = transform(awslogsData); // Steuernachrichten überspringen if (!elastischesearchBulkData)  Konsole.log('Eine Kontrollnachricht erhalten'); Kontext.success('Steuernachricht erfolgreich verarbeitet'); Rückkehr;  // Dokumente an den Amazon Elasticsearch Service posten post(elasticsearchBulkData, function(error, success, statusCode, failedItems)  console.log('Antwort: ' + JSON.stringify( "statusCode": statusCode )); if (Fehler)  logFailure (Fehler, fehlgeschlagene Elemente); Kontext.fehlgeschlagen (JSON.stringify(Fehler));  sonst  Konsole.log('Erfolg: ' + JSON.stringify (Erfolg)); Kontext.erfolgreich('Erfolg');  ); ); ; Funktion transform(Nutzlast)  if (Nutzlast.messageType === 'CONTROL_MESSAGE')  return null;  var BulkRequestBody ="; Nutzlast.logEvents.forEach(function(logEvent)  var timestamp = new Date(1 * logEvent.Zeitstempel); // Format des Indexnamens: cwl-YYYY.MM.DD //var indexName = [ //'cwl-' + Zeitstempel.getUTCFullYear(), // Jahr //('0' + (Zeitstempel.getUTCMonth() + 1)).Slice(-2), // Monat //('0' + Zeitstempel.getUTCDate()).Slice(-2) // Tag //].beitreten('.'); // Format des Indexnamens: cwl-YYYY.MM.DD //var appName =payload.logGruppe.toLowerCase(); //var indexName ="; var indexName = [ 'cwl-' + Nutzlast.logGroup.toLowerCase().Teilt('/').join('-') + '-' + Zeitstempel.getUTCFullYear(), // Protokollgruppe + Jahr ('0' + (Zeitstempel.getUTCMonth() + 1)).Slice(-2), // Monat ('0' + Zeitstempel.getUTCDate()).Slice(-2) // Tag ].beitreten('.'); var source = buildSource(logEvent.Nachricht, logEvent.extrahierte Felder); source['@id'] = logEvent.Ich würde; source['@timestamp'] = neues Datum(1 * logEvent.Zeitstempel).toISOString(); source['@message'] = logEvent.Botschaft; source['@owner'] = Nutzlast.Inhaber; source['@log_group'] = Nutzlast.logGruppe; source['@log_stream'] = Nutzlast.logStream; var Aktion =  "index":  ; Aktion.Index._index = indexName; Aktion.Index._Typ = Nutzlast.logGruppe; Aktion.Index._id = logEvent.Ich würde; BulkRequestBody += [ JSON.stringify(Aktion), JSON.stringify(Quelle), ].beitreten('\n') + '\n'; ); Rückgabe von BulkRequestBody;  Funktion buildSource (Nachricht, ExtractedFields)  if (extractedFields)  var source = ; for (var-Schlüssel in ExtractedFields)  if (extractedFields.hasOwnProperty(key) && ExtractedFields[key])  var Wert = ExtractedFields[key]; if (isNumeric(value))  source[key] = 1 * value; fortsetzen;  jsonSubString = ExtractJson(Wert); if (jsonSubString !== null)  source['$' + key] = JSON.parse(jsonSubString);  Quelle[Schlüssel] = Wert;   Quelle zurückgeben;  jsonSubString = ExtractJson(Nachricht); if (jsonSubString !== null)  JSON zurückgeben.parse(jsonSubString);  Rückkehr ;  Funktion ExtractJson (Nachricht)  var jsonStart = Nachricht.Index von(''); if (jsonStart < 0) return null; var jsonSubString = message.substring(jsonStart); return isValidJson(jsonSubString) ? jsonSubString : null;  function isValidJson(message)  try  JSON.parse(message);  catch (e)  return false;  return true;  function isNumeric(n)  return !isNaN(parseFloat(n)) && isFinite(n);  function post(body, callback)  var requestParams = buildRequest(endpoint, body); var request = https.request(requestParams, function(response)  var responseBody ="; response.on('data', function(chunk)  responseBody += chunk; ); response.on('end', function()  var info = JSON.parse(responseBody); var failedItems; var success; var error; if (response.statusCode >= 200 && Antwort.Statuscode < 299)  failedItems = info.items.filter(function(x)  return x.index.status >= 300; ); success =  "attemptedItems": info.Artikel.Länge, "successfulItems": info.Artikel.Länge - failedItemsIt.Länge, "failedItems": failedItems.Länge;  if (Antwort.Statuscode !== 200 || die Info.error === true)  // verhindert das Protokollieren von fehlgeschlagenen Einträgen, ermöglicht aber das Protokollieren // anderer Fehler wie z. B. Zugriffsbeschränkungen delete info.Artikel; error =  statusCode: antwort.statusCode, responseBody: info ;  Rückruf(Fehler, Erfolg, Antwort.statusCode, failedItems); ); ).on('Fehler', Funktion(e)  Rückruf(e);); Anfrage.Ende(AnfrageParams.Körper);  Funktion buildRequest(endpoint, body)  var endpointParts = endpoint.übereinstimmen(/^([^\.]+)\.?([^\.]*)\.?([^\.]*)\.Amazonas\.com$/); var region = endpointParts[2]; var service = endpointParts[3]; var datetime = (neues Datum()).toISOString().ersetzen(/[:\-]|\.\d3/g,"); var date = datetime.substr(0, 8); var kDate = hmac('AWS4' + Prozess.env.AWS_SECRET_ACCESS_KEY, Datum); var kRegion = hmac(kDatum, Region); var kService = hmac(kRegion, Dienst); var kSigning = hmac(kService, 'aws4_request'); var request =  host: endpoint, method: 'POST', path: '/_bulk', body: body, headers:  'Content-Type': 'application/json', 'Host': endpoint, 'Content-Length ': Puffer.byteLength(body), 'X-Amz-Security-Token': Prozess.env.AWS_SESSION_TOKEN, 'X-Amz-Datum': Datum/Uhrzeit  ; var CanonicalHeaders = Objekt.Schlüssel (Anfrage.Kopfzeilen) .sort(funktion(a, b)  Rückgabe a.toLowerCase() < b.toLowerCase() ? -1 : 1; ) .map(function(k)  return k.toLowerCase() + ':' + request.headers[k]; ) .join('\n'); var signedHeaders = Object.keys(request.headers) .map(function(k)  return k.toLowerCase(); ) .sort() .join(';'); var canonicalString = [ request.method, request.path,", canonicalHeaders,", signedHeaders, hash(request.body, 'hex'), ].join('\n'); var credentialString = [ date, region, service, 'aws4_request' ].join('/'); var stringToSign = [ 'AWS4-HMAC-SHA256', datetime, credentialString, hash(canonicalString, 'hex') ] .join('\n'); request.headers.Authorization = [ 'AWS4-HMAC-SHA256 Credential="+ process.env.AWS_ACCESS_KEY_ID +"/' + credentialString, 'SignedHeaders=' + signedHeaders, 'Signature=' + hmac(kSigning, stringToSign, 'hex') ].join(', '); return request;  function hmac(key, str, encoding)  return crypto.createHmac('sha256', key).update(str, 'utf8').digest(encoding);  function hash(str, encoding)  return crypto.createHash('sha256').update(str, 'utf8').digest(encoding);  function logFailure(error, failedItems)  if (logFailedResponses)  console.log('Error: ' + JSON.stringify(error, null, 2)); if (failedItems && failedItems.length > 0)  Konsole.log("Fehlgeschlagene Elemente: " + JSON.stringify(failedItems, null, 2));   

Sie können jetzt mehrere Log-Streams zu Ihrem Elasticsearch-Cluster Kibana streamen.

Wichtige Links

Zum Thema passende Artikel:

AWS Learning-Kurse:AWS Certified Solutions Architect - Associate 2020AWS-zertifizierter Lösungsarchitekt - Associate 2020$12.06$156.75auf LagerJETZT KAUFENUdemy.comUltimativer AWS Certified Solutions Architect Associate 2020Ultimativer AWS Certified Solutions Architect Associate 2020$12.06$156.75auf LagerJETZT KAUFENUdemy.comAWS-zertifizierter Entwickler - Associate 2020AWS-zertifizierter Entwickler - Associate 202015 $.68180 $.87auf LagerJETZT KAUFENUdemy.comUltimativer AWS Certified Developer Associate 2020 – NEU!Ultimativer AWS Certified Developer Associate 2020 – NEU!$20.50$241.17auf LagerJETZT KAUFENUdemy.com

So minimieren, optimieren und sichern Sie Docker-Container mit DockerSlim
DockerSlim ist ein Open-Source-Tool, mit dem Sie Ihre Docker-Container bis zu 30-mal sichern und minimieren können! Lassen Sie uns nun zunächst erfahr...
Installieren Sie CRI-O Container Runtime auf CentOS 8 / CentOS 7
CRI-O ist eine OCI-basierte Implementierung von Kubernetes Container Runtime Interface (CRI). CRI-O soll einen Integrationspfad zwischen OCI-konformen...
Red Hat OpenShift 4 Neue Funktionen
EinführungDie Titel bei Red Hat vor wenigen Tagen hießen: „Red Hat definiert Enterprise Kubernetes durch vollständige Stack-Automatisierung mit Red Ha...