Skip to content

Commit ca9e0f4

Browse files
committed
RGW/logging: add filtering for bucket logging
Signed-off-by: Ali Masarwa <[email protected]>
1 parent bb40fe4 commit ca9e0f4

File tree

11 files changed

+470
-295
lines changed

11 files changed

+470
-295
lines changed

doc/radosgw/bucket_logging.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ Journal
3838
If logging type is set to "Journal", the records are written to the log bucket before the bucket operation is completed.
3939
This means that if the logging action fails, the operation will not be executed, and an error will be returned to the client.
4040
An exception to the above are "multi/delete" log records: if writing these log records fail, the operation continues and may still be successful.
41-
Note that it may happen that the log records were successfully written, but the bucket operation failed, since the logs are written
42-
before such a failure, there will be no indication for that in the log records.
41+
Journal mode supports filtering out records based on matches of the prefixes and suffixes of the logged object keys. Regular-expression matching can also be used on these to create filters.
42+
Note that it may happen that the log records were successfully written, but the bucket operation failed, since the logs are written.
4343

4444

4545
Bucket Logging REST API

doc/radosgw/s3/bucketops.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,26 @@ Parameters are XML encoded in the body of the request, in the following format:
751751
<TargetPrefix>string</TargetPrefix>
752752
<LoggingType>Standard|Journal</LoggingType>
753753
<ObjectRollTime>integer</ObjectRollTime>
754+
<Filter>
755+
<S3Key>
756+
<FilterRule>
757+
<Name>suffix/prefix/regex</Name>
758+
<Value></Value>
759+
</FilterRule>
760+
</S3Key>
761+
<S3Metadata>
762+
<FilterRule>
763+
<Name></Name>
764+
<Value></Value>
765+
</FilterRule>
766+
</S3Metadata>
767+
<S3Tags>
768+
<FilterRule>
769+
<Name></Name>
770+
<Value></Value>
771+
</FilterRule>
772+
</S3Tags>
773+
</Filter>
754774
</LoggingEnabled>
755775
</BucketLoggingStatus>
756776

@@ -881,6 +901,26 @@ Response is XML encoded in the body of the request, in the following format:
881901
<TargetPrefix>string</TargetPrefix>
882902
<LoggingType>Standard|Journal</LoggingType>
883903
<ObjectRollTime>integer</ObjectRollTime>
904+
<Filter>
905+
<S3Key>
906+
<FilterRule>
907+
<Name>suffix/prefix/regex</Name>
908+
<Value></Value>
909+
</FilterRule>
910+
</S3Key>
911+
<S3Metadata>
912+
<FilterRule>
913+
<Name></Name>
914+
<Value></Value>
915+
</FilterRule>
916+
</S3Metadata>
917+
<S3Tags>
918+
<FilterRule>
919+
<Name></Name>
920+
<Value></Value>
921+
</FilterRule>
922+
</S3Tags>
923+
</Filter>
884924
</LoggingEnabled>
885925
</BucketLoggingStatus>
886926

examples/rgw/boto3/bucket_logging.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@
3939
},
4040
'ObjectRollTime': 60,
4141
'LoggingType': 'Journal',
42+
"Filter": {
43+
"Key": {
44+
"FilterRules":
45+
[
46+
{
47+
"Name": "prefix",
48+
"Value": "myfile"
49+
}
50+
]
51+
}
52+
}
4253
}
4354
}
4455

examples/rgw/boto3/service-2.sdk-extras.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@
287287
"RecordsBatchSize":{
288288
"shape":"RecordsBatchSize",
289289
"documentation":"indicates how many records to batch in memory before writing to the object. if set to zero, records are written syncronously to the object. if <code>ObjectRollTime</code>e is reached, the batch of records will be written to the object regardless of the number of records. </p>"
290+
},
291+
"Filter":{
292+
"shape":"NotificationConfigurationFilter",
293+
"documentation":"<p>A filter for all log object. Types of filter for the object by its: attributes, tags and key (prefix, suffix and regex).</p>"
290294
}
291295
},
292296
"documentation":"<p>Describes where logs are stored the prefix assigned to all log object keys for a bucket, and their format. also, the level the delivery guarantee of the records.</p>"

src/rgw/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ set(librgw_common_srcs
9090
rgw_notify_event_type.cc
9191
rgw_period_history.cc
9292
rgw_period_puller.cc
93+
rgw_s3_filter.cc
9394
rgw_pubsub.cc
9495
rgw_coroutine.cc
9596
rgw_cr_rest.cc

src/rgw/rgw_bucket_logging.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ bool configuration::decode_xml(XMLObj* obj) {
3131
logging_type = LoggingType::Standard;
3232
} else if (type == "Journal") {
3333
logging_type = LoggingType::Journal;
34+
RGWXMLDecoder::decode_xml("Filter", s3_filter, o);
3435
} else {
3536
// we don't allow for type "Any" in the configuration
3637
throw RGWXMLDecoder::err("invalid bucket logging record type: '" + type + "'");
@@ -73,6 +74,9 @@ void configuration::dump_xml(Formatter *f) const {
7374
break;
7475
case LoggingType::Journal:
7576
::encode_xml("LoggingType", "Journal", f);
77+
if (s3_filter.has_content()) {
78+
::encode_xml("Filter", s3_filter, f);
79+
}
7680
break;
7781
case LoggingType::Any:
7882
::encode_xml("LoggingType", "", f);
@@ -118,6 +122,9 @@ void configuration::dump(Formatter *f) const {
118122
break;
119123
case LoggingType::Journal:
120124
encode_json("loggingType", "Journal", f);
125+
if (s3_filter.has_content()) {
126+
encode_json("Filter", s3_filter, f);
127+
}
121128
break;
122129
case LoggingType::Any:
123130
encode_json("loggingType", "", f);
@@ -526,6 +533,11 @@ int log_record(rgw::sal::Driver* driver,
526533
if (type != LoggingType::Any && configuration.logging_type != type) {
527534
return 0;
528535
}
536+
if (configuration.s3_filter.has_content()) {
537+
if (!match(configuration.s3_filter, obj)) {
538+
return 0;
539+
}
540+
}
529541
ldpp_dout(dpp, 20) << "INFO: found matching logging configuration of bucket '" << s->bucket->get_name() <<
530542
"' configuration: " << configuration.to_json_str() << dendl;
531543
if (auto ret = log_record(driver, obj, s, op_name, etag, size, configuration, dpp, y, async_completion, log_source_bucket); ret < 0) {

src/rgw/rgw_bucket_logging.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "include/buffer.h"
1111
#include "include/encoding.h"
1212
#include "common/async/yield_context.h"
13+
#include "rgw_s3_filter.h"
1314

1415
class XMLObj;
1516
namespace ceph { class Formatter; }
@@ -48,6 +49,26 @@ namespace rgw::bucketlogging {
4849
<LoggingType>Standard|Journal</LoggingType> <!-- Ceph extension -->
4950
<ObjectRollTime>integer</ObjectRollTime> <!-- Ceph extension -->
5051
<RecordsBatchSize>integer</RecordsBatchSize> <!-- Ceph extension -->
52+
<Filter>
53+
<S3Key>
54+
<FilterRule>
55+
<Name>suffix/prefix/regex</Name>
56+
<Value></Value>
57+
</FilterRule>
58+
</S3Key>
59+
<S3Metadata>
60+
<FilterRule>
61+
<Name></Name>
62+
<Value></Value>
63+
</FilterRule>
64+
</S3Metadata>
65+
<S3Tags>
66+
<FilterRule>
67+
<Name></Name>
68+
<Value></Value>
69+
</FilterRule>
70+
</S3Tags>
71+
</Filter>
5172
</LoggingEnabled>
5273
</BucketLoggingStatus>
5374
*/
@@ -78,6 +99,7 @@ struct configuration {
7899
PartitionDateSource date_source = PartitionDateSource::DeliveryTime;
79100
// EventTime: use only year, month, and day. The hour, minutes and seconds are set to 00 in the key
80101
// DeliveryTime: the time the log object was created
102+
rgw_s3_filter s3_filter;
81103
bool decode_xml(XMLObj *obj);
82104
void dump_xml(Formatter *f) const;
83105
void dump(Formatter *f) const; // json
@@ -92,6 +114,9 @@ struct configuration {
92114
encode(static_cast<int>(logging_type), bl);
93115
encode(records_batch_size, bl);
94116
encode(static_cast<int>(date_source), bl);
117+
if (logging_type == LoggingType::Journal) {
118+
encode(s3_filter, bl);
119+
}
95120
ENCODE_FINISH(bl);
96121
}
97122

@@ -108,6 +133,9 @@ struct configuration {
108133
decode(records_batch_size, bl);
109134
decode(type, bl);
110135
date_source = static_cast<PartitionDateSource>(type);
136+
if (logging_type == LoggingType::Journal) {
137+
decode(s3_filter, bl);
138+
}
111139
DECODE_FINISH(bl);
112140
}
113141
};

0 commit comments

Comments
 (0)