Bucket logging
Bucket logging records all access requests to a bucket and stores them as log objects in a separate log bucket. The log data can be used to monitor bucket activity, detect unauthorized access, analyze usage patterns, and maintain an audit trail of bucket changes.
Logging is configured at the bucket level and can be enabled or disabled at any time. The log bucket can collect logs from multiple source buckets. To distinguish logs from different buckets, configure a unique prefix for each source bucket so that the logs are stored in separate objects within the log bucket.Before enabling logging, ensure that the log bucket is created. The log bucket cannot be the same as the source bucket, and it cannot have logging, compression, or server-side encryption (SSE-S3 or SSE-C) enabled. It must not have RequestPayer enabled. Source and log buckets must be in the same zonegroup, but they can belong to different accounts if the log bucket policy allows it.
The logs are stored as objects in a dedicated log bucket, which can collect events from multiple source buckets. Each source bucket should be configured with a unique prefix so that logs are written to separate objects within the log bucket.
Logging modes
Bucket logging supports two modes that differ in reliability guarantees and in the bucket operations they record.
Standard mode
In Standard mode, log records are written to the log bucket after the bucket operation completes. Failures in logging do not affect the bucket operation. Logs follow the AWS-compatible standard record format, which includes information such as request ID, client IP, HTTP status, and user agent.
Journal mode
PutObject, CopyObject, CompleteMultipartUpload, PutObjectAcl, PutObjectLegalHold, PutObjectRetention, and PutObjectTagging— if logging fails, the operation fails.DeleteObject, DeleteObjects, and DeleteObjectTagging— the operation continues even if logging fails.
Reliability and flushing
Log objects do not appear in the log bucket immediately. By default, log objects are rolled every five minutes or when they reach 128 MB in size.Log objects can be flushed manually. Automatic flush occurs when logging is disabled, when the configuration changes, or when the source bucket is deleted. The time (in seconds) can be set per source bucket via a Ceph extension to the REST API , or globally via the rgw_bucket_logging_obj_roll_time configuration option. If not set, the default time is 5 minutes.
Multisite
In multisite deployments, each zone maintains temporary log objects before they are flushed to the log bucket. After flushing, log objects are then replicated across all zones similar to other objects sync in a multisite.
Policies and quotas
s3:PutObject action for the logging.s3.amazonaws.com service principal. The policy should also specify the source bucket and account that are permitted to write logs.Bucket and user quotas apply to the log bucket:
- In Journal mode, exceeding quota causes both logging and the bucket operation to fail.
- In Standard mode, logging is skipped, but the bucket operation continues successfully.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowLoggingFromSourceBucket",
"Effect": "Allow",
"Principal": {
"Service": "logging.s3.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::log-bucket-name/prefix*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "source-account-id"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::source-bucket-name"
}
}
}
]
}
Log Objects Key Format
There are two types of log object key formats: Simple and Partitioned.
<prefix><year-month-day-hour-minute-second>-<16-byte-unique-id>
For example,
fish/2024-08-06-09-40-09-0000000002AGQ6W1
<prefix><source-bucket-owner>/<zone-group>/[tenant:]<source-bucket-name>/<year>/<month>/<day>/<year-month-day-hour-minute-second>-<16-byte-unique-id>
fish/testid/default/fish-bucket/2024/08/06/2024-08-06-10-11-18-0000000011D1FGPA
Log record formats
- Journal format
- A minimal Ceph-specific record used for journaling bucket changes.
- Standard format
- AWS-compatible record format with extended metadata fields such as request ID, client IP, and HTTP status.
- bucket owner (or dash if empty)
- bucket name (or dash if empty), in the format:
[tenant:]<bucket name> - time in the following format:
[day/month/year:hour:minute:second timezone] - operation in the following format:
WEBSITE/REST.<HTTP method>.<resource> - object key (or dash if empty)
- object size (or dash if empty
- version id (or dash if empty)
- eTag (or dash if empty)
testid fish [06/Aug/2024:09:40:09 +0000] REST.PUT.OBJECT myfile - 512 4cfdfc1f58e762d3e116787cb92fac60 testid fish [06/Aug/2024:09:40:28 +0000] REST.DELETE.OBJECT myfile - - 4cfdfc1f58e762d3e116787cb92fac60
- bucket owner (or dash if empty)
- bucket name (or dash if empty) in the format:
[tenant:]<bucket name> - time in the following format:
[day/month/year:hour:minute:second timezone]where “timezone” is in UTC offset - client IP address (or dash if empty)
- user or account (or dash if empty)
- request ID
- operation in the following format:
WEBSITE/REST.<HTTP method>.<resource> - object key (or dash if empty)
- request URI in the following format:
"<HTTP method> <URI> <HTTP version>" - HTTP status (or dash if zero). Note that in most cases log is written before the status is known
- error code (or dash if empty)
- bytes sent (or dash if zero)
- object size (or dash if zero)
- total time (not supported, always a dash)
- turnaround time in milliseconds
- referer (or dash if empty)
- user agent (or dash if empty) inside double quotes
- version id (or dash if empty)
- host id taken from
x-amz-id-2(or dash if empty) - signature version (or dash if empty)
- cipher suite (or dash if empty)
- authentication type (
AuthHeaderfor regular auth,QueryStringfor presigned URL or dash if unauthenticated) - host header (or dash if empty)
- TLS version (or dash if empty)
- access point ARN (not supported, always a dash)
- ACL flag (
Yesif an ACL was required for authorization, otherwise dash)
testid fish [06/Aug/2024:09:30:25 +0000] - testid 9e369a15-5f43-4f07-b638-de920b22f91b.4179.15085270386962380710 REST.PUT.OBJECT myfile "PUT /fish/myfile HTTP/1.1" 200 - 512 512 - - - - - - - - - localhost - - testid fish [06/Aug/2024:09:30:51 +0000] - testid 9e369a15-5f43-4f07-b638-de920b22f91b.4179.7046073853138417766 REST.GET.OBJECT myfile "GET /fish/myfile HTTP/1.1" 200 - - 512 - - - - - - - - - localhost - - testid fish [06/Aug/2024:09:30:56 +0000] - testid 9e369a15-5f43-4f07-b638-de920b22f91b.4179.10723158448701085570 REST.DELETE.OBJECT myfile "DELETE /fish/myfile1 HTTP/1.1" 200 - - 512 - - - - - - - - - localhost - -