Comment analyser les journaux d'accès au serveur Amazon S3 à l'aide d'Athena ?

Dernière mise à jour : 17-12-2021

Comment interroger les journaux d'accès au serveur Amazon Simple Storage Service (Amazon S3) dans Amazon Athena ?

Résolution

Amazon S3 stocke les journaux d'accès au serveur en tant qu'objets dans un compartiment S3. Pour analyser rapidement et interroger les journaux d'accès au serveur, vous pouvez utiliser Athena.

1.    Activez la journalisation des accès au serveur de votre compartiment S3, si vous ne l'avez pas déjà fait. Notez les valeurs de Taget bucket (Compartiment cible) et de Target prefix (Préfixe cible). Vous avez besoin de ces deux valeurs pour spécifier l'emplacement Amazon S3 dans une requête Athena.

2.    Ouvrez la console Amazon Athena.

3.    Dans l'éditeur de requêtes, exécutez une instruction DDL pour créer une base de données. Il est recommandé de créer la base de données dans la même région AWS que votre compartiment S3.

create database s3_access_logs_db

4.    Créez un schéma de table dans la base de données. Dans l'exemple suivant, les valeurs de type de données STRING et BIGINT sont les propriétés des journaux d'accès. Vous pouvez interroger ces propriétés dans Athena. Pour LOCATION, saisissez le compartiment S3 et le préfixe du chemin de l'étape 1. Veillez à inclure une barre oblique (/) à la fin du préfixe (par exemple, s3://doc-example-bucket/prefix/). Si vous n'utilisez pas de préfixe, ajoutez une barre oblique (/) à la fin du nom du compartiment (par exemple, s3://doc-example-bucket/).

CREATE EXTERNAL TABLE `s3_access_logs_db.mybucket_logs`(
  `bucketowner` STRING,
  `bucket_name` STRING,
  `requestdatetime` STRING,
  `remoteip` STRING,
  `requester` STRING,
  `requestid` STRING,
  `operation` STRING,
  `key` STRING,
  `request_uri` STRING,
  `httpstatus` STRING,
  `errorcode` STRING,
  `bytessent` BIGINT,
  `objectsize` BIGINT,
  `totaltime` STRING,
  `turnaroundtime` STRING,
  `referrer` STRING,
  `useragent` STRING,
  `versionid` STRING,
  `hostid` STRING,
  `sigv` STRING,
  `ciphersuite` STRING,
  `authtype` STRING,
  `endpoint` STRING,
  `tlsversion` STRING)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$')
STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://awsexamplebucket1-logs/prefix/'

5.    Dans le volet gauche, sous Tables, choisissez Preview table (Aperçu de la table) avec le bouton de menu en regard du nom de la table. Si des données de journaux d'accès au serveur figurent dans la fenêtre Results (Résultats) (par exemple, bucketowner, bucket, requestdatetime, etc.), cela signifie que la table Athena a été créée avec succès. Vous pouvez désormais interroger les journaux d'accès au serveur Amazon S3.

Exemples de requêtes

Pour rechercher la requête d'un objet supprimé, utilisez la requête suivante :

SELECT * FROM s3_access_logs_db.mybucket_logs WHERE
key = 'images/picture.jpg' AND operation like '%DELETE%';

Pour afficher les ID de requête Amazon S3 pour les demandes ayant entraîné des erreurs 403 Access Denied, utilisez la requête suivante :

SELECT requestdatetime, requester, operation, requestid, hostid FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus = '403';

Pour rechercher les ID de requête Amazon S3 pour les erreurs HTTP 5xx au cours d'une période donnée (y compris la clé et le code d'erreur), exécutez la requête suivante :

SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus like '5%' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:07:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-18:08:00:00','yyyy-MM-dd:HH:mm:ss');

Pour afficher qui a supprimé un objet et quand, y compris l'horodatage, l'adresse IP et le rôle AWS Identity and Access Management (IAM), utilisez la requête suivante :

SELECT requestdatetime, remoteip, requester, key FROM s3_access_logs_db.mybucket_logs WHERE
key = 'images/picture.jpg' AND operation like '%DELETE%';

Pour afficher toutes les opérations effectuées par un rôle IAM, utilisez la requête suivante :

SELECT * FROM s3_access_logs_db.mybucket_logs WHERE
requester='arn:aws:iam::123456789123:user/user_name';

Pour afficher toutes les opérations effectuées sur un objet au cours d'une période spécifique, utilisez la requête suivante :

SELECT SUM(bytessent) as uploadtotal,
SUM(objectsize) as downloadtotal,
SUM(bytessent + objectsize) AS total FROM s3_access_logs_db.mybucket_logs
WHERE remoteIP='1.2.3.4' AND 
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01','yyyy-MM-dd')
AND parse_datetime('2021-08-01','yyyy-MM-dd');

Pour afficher la quantité de données transférées via une adresse IP au cours d'une période donnée, utilisez la requête suivante :

SELECT SUM(bytessent) as uploadtotal,
SUM(objectsize) as downloadtotal,
SUM(bytessent + objectsize) AS total FROM s3_access_logs_db.mybucket_logs
WHERE remoteIP='1.2.3.4' AND 
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01','yyyy-MM-dd')
AND parse_datetime('2021-08-01','yyyy-MM-dd');

Pour afficher toutes les opérations d'expiration effectuées par les règles de cycle de vie au cours d'une période donnée, utilisez la requête suivante :

SELECT *
FROM s3_access_logs_db.mybucket_logs
WHERE operation = 'S3.EXPIRE.OBJECT' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');

Pour compter le nombre d'objets expirés au cours d'une période donnée, utilisez la requête suivante :

SELECT count(*) as ExpireCount
FROM s3_access_logs_db.mybucket_logs
WHERE operation = 'S3.EXPIRE.OBJECT' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');

Pour afficher toutes les opérations de transition effectuées par les règles de cycle de vie au cours d'une période donnée, utilisez la requête suivante :

SELECT * FROM s3_access_logs_db.mybucket_logs
WHERE operation like 'S3.TRANSITION%' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss');

Pour afficher tous les demandeurs regroupés par version de signature, utilisez la requête suivante :

SELECT requester, Sigv, Count(Sigv) as SigCount
FROM s3_access_logs_db.mybucket_logs
GROUP BY requester, Sigv;

Pour afficher tous les demandeurs anonymes qui font des demandes au cours d'une période donnée, utilisez la requête suivante :

SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db.mybucket_logs
WHERE Requester IS NULL AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')

Pour afficher tous les demandeurs qui envoient des demandes d'objet PUT au cours d'une période donnée, utilisez la requête suivante :

SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db
WHERE Operation='REST.PUT.OBJECT' AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')

Pour afficher tous les demandeurs qui envoient des demandes d'objet GET au cours d'une période donnée, utilisez la requête suivante :

SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db
WHERE Operation='REST.GET.OBJECT' AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')

Pour afficher tous les demandeurs anonymes qui font des demandes au cours d'une période donnée, utilisez la requête suivante :

SELECT Bucket, Requester, RemoteIP, Key, HTTPStatus, ErrorCode, RequestDateTime
FROM s3_access_logs_db.mybucket_logs
WHERE Requester IS NULL AND
parse_datetime(RequestDateTime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')

Pour afficher tous les demandeurs (classés par délai d'exécution le plus élevé au cours d'une période donnée), utilisez la requête suivante :

SELECT * FROM s3_access_logs_db.mybucket_logs
NOT turnaroundtime='-' AND
parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2021-09-18:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND
parse_datetime('2021-09-19:00:00:00','yyyy-MM-dd:HH:mm:ss')
ORDER BY CAST(turnaroundtime AS INT) DESC;

Il est recommandé de créer une stratégie de cycle de vie pour votre compartiment de journaux d'accès au serveur. Configurez la stratégie de cycle de vie pour supprimer périodiquement les fichiers journaux. Cela réduit la quantité de données analysées par Athena pour chaque requête.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?