Bei Verwendung von statischem Website-Hosting spielt es eine Rolle als Zugriffsprotokoll. Es handelt sich um eine Protokollierungsfunktion, die das Protokoll der Anforderung an S3 an den angegebenen Bucket weiterleitet, eine Aktualisierungsbenachrichtigung (Ereignis-Nortifizierung) in den Ziel-Bucket einfügt und Lambda startet. Tauchen Sie in BigQuery ein, damit es abgerufen, analysiert und analysiert werden kann.
Es ist hier geschrieben. https://docs.aws.amazon.com/AmazonS3/latest/dev/LogFormat.html
Das Gefühl, dass jede Beschriftung direkt dem Spaltennamen im nächsten Schema entspricht.
^(?P<owner>[^ ]+) (?P<bucket>[^ ]+) \[(?P<datetime>.+)\](?P<remote_ip>[^ ]+) (?P<requester>[^ ]+) (?P<request_id>[^ ]+) (?P<operation>[^ ]+) (?P<key>[^ ]+) "(?P<method>[^ ]+) (?P<uri>[^ ]+) (?P<proto>.+)" (?P<status>[^ ]+) (?P<error>[^ ]+) (?P<bytes>[^ ]+) (?P<size>[^ ]+) (?P<total_time>[^ ]+) (?P<ta_time>[^ ]+) "(?P<referrer>.+)" "(?P<user_agent>.+)" (?P<version>.+)$
Es sieht je nach Format so aus. Die Spalte "datetime" scheint für den TIMESTAMP-Typ besser zu sein, aber ich habe diesmal STRING aufgrund der Umstände gewählt, wie ich später ausführlich erläutern werde.
Spaltenname | Schimmel |
---|---|
owner | STRING |
bucket | STRING |
datetime | STRING |
remote_ip | STRING |
requester | STRING |
request_id | STRING |
operation | STRING |
key | STRING |
method | STRING |
uri | STRING |
proto | STRING |
status | STRING |
error | STRING |
bytes | INTEGER |
size | INTEGER |
total_time | INTEGER |
ta_time | INTEGER |
referrer | STRING |
user_agent | STRING |
version | STRING |
Bitte ersetzen Sie das <your - *>
Teil entsprechend.
import os
import json
import urllib
import boto3
import re
import datetime
import pytz
from gcloud import bigquery
BQ_PROJECT = '<your-project-id>'
BQ_DATASET = '<your-dataset-name>'
BQ_TABLE = '<your-table-name>'
s3 = boto3.client('s3')
bq = bigquery.Client.from_service_account_json(
os.path.join(os.path.dirname(__file__), 'bq.json'),
project=BQ_PROJECT)
dataset = bq.dataset(BQ_DATASET)
table = dataset.table(name=BQ_TABLE)
table.reload()
pattern = ' '.join([
'^(?P<owner>[^ ]+)',
'(?P<bucket>[^ ]+)',
'\[(?P<datetime>.+)\]',
'(?P<remote_ip>[^ ]+)',
'(?P<requester>[^ ]+)',
'(?P<request_id>[^ ]+)',
'(?P<operation>[^ ]+)',
'(?P<key>[^ ]+)',
'"(?P<method>[^ ]+) (?P<uri>[^ ]+) (?P<proto>.+)"',
'(?P<status>[^ ]+)',
'(?P<error>[^ ]+)',
'(?P<bytes>[^ ]+)',
'(?P<size>[^ ]+)',
'(?P<total_time>[^ ]+)',
'(?P<ta_time>[^ ]+)',
'"(?P<referrer>.+)"',
'"(?P<user_agent>.+)"',
'(?P<version>.+)$'])
log_pattern = re.compile(pattern)
def to_int(val):
try:
ret = int(val)
except ValueError:
ret = None
return ret
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
res = s3.get_object(Bucket=bucket, Key=key)
body = res['Body'].read()
rows = []
for line in body.splitlines():
matches = log_pattern.match(line)
dt_str = matches.group('datetime').split(' ')[0]
timestamp = datetime.datetime.strptime(
dt_str, '%d/%b/%Y:%H:%M:%S').replace(tzinfo=pytz.utc)
rows.append((
matches.group('owner'),
matches.group('bucket'),
timestamp.strftime('%Y-%m-%d %H:%M:%S'),
matches.group('remote_ip'),
matches.group('requester'),
matches.group('request_id'),
matches.group('operation'),
matches.group('key'),
matches.group('method'),
matches.group('uri'),
matches.group('proto'),
matches.group('status'),
matches.group('error'),
to_int(matches.group('bytes')),
to_int(matches.group('size')),
to_int(matches.group('total_time')),
to_int(matches.group('ta_time')),
matches.group('referrer'),
matches.group('user_agent'),
matches.group('version'),))
print(table.insert_data(rows))
bq.json
[^ 1] in das Lambda-Funktionsbereitstellungspaket ein.gcloud (0.8.0)
? Beachten Sie, dass BigQuery in Sekunden angegeben ist. Der Versuch, in Millisekunden zu speichern, führt jedoch zu einem unmöglichen Datum.Übrigens ist die Bereitstellung von Lambda für Python meine Arbeit, aber ich verwende Folgendes. Es befindet sich noch in der Entwicklung, aber es wird immer bequemer, es normal zu verwenden. Probieren Sie es also aus, wenn Sie möchten. https://github.com/marcy-terui/lamvery
[^ 1]: Suche nach einer intelligenten Möglichkeit, vertrauliche Informationen in Lambda zu übertragen [^ 2]: Wo Sie Python3-Unterstützung so schnell wie möglich wünschen
Recommended Posts