]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_log.h
import ceph quincy 17.2.4
[ceph.git] / ceph / src / rgw / rgw_log.h
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae
FG
3
4#ifndef CEPH_RGW_LOG_H
5#define CEPH_RGW_LOG_H
9f95a23c 6
7c673cae
FG
7#include <boost/container/flat_map.hpp>
8#include "rgw_common.h"
7c673cae 9#include "common/OutputDataSocket.h"
a4b75251
TL
10#include <vector>
11#include <fstream>
12
13#define dout_subsys ceph_subsys_rgw
7c673cae 14
20effc67
TL
15namespace rgw { namespace sal {
16 class Store;
17} }
7c673cae
FG
18
19struct rgw_log_entry {
20
21 using headers_map = boost::container::flat_map<std::string, std::string>;
11fdf7f2 22 using Clock = req_state::Clock;
7c673cae
FG
23
24 rgw_user object_owner;
25 rgw_user bucket_owner;
20effc67 26 std::string bucket;
11fdf7f2 27 Clock::time_point time;
20effc67
TL
28 std::string remote_addr;
29 std::string user;
7c673cae 30 rgw_obj_key obj;
20effc67
TL
31 std::string op;
32 std::string uri;
33 std::string http_status;
34 std::string error_code;
9f95a23c
TL
35 uint64_t bytes_sent = 0;
36 uint64_t bytes_received = 0;
37 uint64_t obj_size = 0;
38 Clock::duration total_time{};
20effc67
TL
39 std::string user_agent;
40 std::string referrer;
41 std::string bucket_id;
7c673cae 42 headers_map x_headers;
20effc67
TL
43 std::string trans_id;
44 std::vector<std::string> token_claims;
45 uint32_t identity_type;
2a845540
TL
46 std::string access_key_id;
47 std::string subuser;
48 bool temp_url {false};
7c673cae
FG
49
50 void encode(bufferlist &bl) const {
2a845540 51 ENCODE_START(13, 5, bl);
11fdf7f2
TL
52 encode(object_owner.id, bl);
53 encode(bucket_owner.id, bl);
54 encode(bucket, bl);
55 encode(time, bl);
56 encode(remote_addr, bl);
57 encode(user, bl);
58 encode(obj.name, bl);
59 encode(op, bl);
60 encode(uri, bl);
61 encode(http_status, bl);
62 encode(error_code, bl);
63 encode(bytes_sent, bl);
64 encode(obj_size, bl);
65 encode(total_time, bl);
66 encode(user_agent, bl);
67 encode(referrer, bl);
68 encode(bytes_received, bl);
69 encode(bucket_id, bl);
70 encode(obj, bl);
71 encode(object_owner, bl);
72 encode(bucket_owner, bl);
73 encode(x_headers, bl);
9f95a23c 74 encode(trans_id, bl);
adb31ebb 75 encode(token_claims, bl);
20effc67 76 encode(identity_type,bl);
2a845540
TL
77 encode(access_key_id, bl);
78 encode(subuser, bl);
79 encode(temp_url, bl);
7c673cae
FG
80 ENCODE_FINISH(bl);
81 }
11fdf7f2 82 void decode(bufferlist::const_iterator &p) {
2a845540 83 DECODE_START_LEGACY_COMPAT_LEN(13, 5, 5, p);
11fdf7f2 84 decode(object_owner.id, p);
7c673cae 85 if (struct_v > 3)
11fdf7f2
TL
86 decode(bucket_owner.id, p);
87 decode(bucket, p);
88 decode(time, p);
89 decode(remote_addr, p);
90 decode(user, p);
91 decode(obj.name, p);
92 decode(op, p);
93 decode(uri, p);
94 decode(http_status, p);
95 decode(error_code, p);
96 decode(bytes_sent, p);
97 decode(obj_size, p);
98 decode(total_time, p);
99 decode(user_agent, p);
100 decode(referrer, p);
7c673cae 101 if (struct_v >= 2)
11fdf7f2 102 decode(bytes_received, p);
7c673cae
FG
103 else
104 bytes_received = 0;
105
106 if (struct_v >= 3) {
107 if (struct_v <= 5) {
108 uint64_t id;
11fdf7f2 109 decode(id, p);
7c673cae 110 char buf[32];
11fdf7f2 111 snprintf(buf, sizeof(buf), "%" PRIu64, id);
7c673cae
FG
112 bucket_id = buf;
113 } else {
11fdf7f2 114 decode(bucket_id, p);
7c673cae
FG
115 }
116 } else {
117 bucket_id = "";
118 }
119 if (struct_v >= 7) {
11fdf7f2 120 decode(obj, p);
7c673cae
FG
121 }
122 if (struct_v >= 8) {
11fdf7f2
TL
123 decode(object_owner, p);
124 decode(bucket_owner, p);
7c673cae
FG
125 }
126 if (struct_v >= 9) {
11fdf7f2 127 decode(x_headers, p);
7c673cae 128 }
9f95a23c
TL
129 if (struct_v >= 10) {
130 decode(trans_id, p);
131 }
adb31ebb
TL
132 if (struct_v >= 11) {
133 decode(token_claims, p);
134 }
20effc67
TL
135 if (struct_v >= 12) {
136 decode(identity_type, p);
137 }
2a845540
TL
138 if (struct_v >= 13) {
139 decode(access_key_id, p);
140 decode(subuser, p);
141 decode(temp_url, p);
142 }
7c673cae
FG
143 DECODE_FINISH(p);
144 }
9f95a23c 145 void dump(ceph::Formatter *f) const;
20effc67 146 static void generate_test_instances(std::list<rgw_log_entry*>& o);
7c673cae
FG
147};
148WRITE_CLASS_ENCODER(rgw_log_entry)
149
a4b75251
TL
150class OpsLogSink {
151public:
152 virtual int log(struct req_state* s, struct rgw_log_entry& entry) = 0;
153 virtual ~OpsLogSink() = default;
154};
155
156class OpsLogManifold: public OpsLogSink {
157 std::vector<OpsLogSink*> sinks;
158public:
159 ~OpsLogManifold() override;
160 void add_sink(OpsLogSink* sink);
161 int log(struct req_state* s, struct rgw_log_entry& entry) override;
162};
163
164class JsonOpsLogSink : public OpsLogSink {
9f95a23c 165 ceph::Formatter *formatter;
a4b75251 166 ceph::mutex lock = ceph::make_mutex("JsonOpsLogSink");
7c673cae
FG
167
168 void formatter_to_bl(bufferlist& bl);
a4b75251
TL
169protected:
170 virtual int log_json(struct req_state* s, bufferlist& bl) = 0;
171public:
172 JsonOpsLogSink();
173 ~JsonOpsLogSink() override;
174 int log(struct req_state* s, struct rgw_log_entry& entry) override;
175};
176
177class OpsLogFile : public JsonOpsLogSink, public Thread, public DoutPrefixProvider {
178 CephContext* cct;
33c7a0ef 179 ceph::mutex mutex = ceph::make_mutex("OpsLogFile");
a4b75251
TL
180 std::vector<bufferlist> log_buffer;
181 std::vector<bufferlist> flush_buffer;
33c7a0ef 182 ceph::condition_variable cond;
a4b75251
TL
183 std::ofstream file;
184 bool stopped;
185 uint64_t data_size;
186 uint64_t max_data_size;
2a845540
TL
187 std::string path;
188 std::atomic_bool need_reopen;
a4b75251
TL
189
190 void flush();
191protected:
192 int log_json(struct req_state* s, bufferlist& bl) override;
193 void *entry() override;
194public:
195 OpsLogFile(CephContext* cct, std::string& path, uint64_t max_data_size);
196 ~OpsLogFile() override;
197 CephContext *get_cct() const override { return cct; }
198 unsigned get_subsys() const override { return dout_subsys; }
199 std::ostream& gen_prefix(std::ostream& out) const override { return out << "rgw OpsLogFile: "; }
2a845540 200 void reopen();
a4b75251
TL
201 void start();
202 void stop();
203};
7c673cae 204
a4b75251 205class OpsLogSocket : public OutputDataSocket, public JsonOpsLogSink {
7c673cae 206protected:
a4b75251 207 int log_json(struct req_state* s, bufferlist& bl) override;
7c673cae
FG
208 void init_connection(bufferlist& bl) override;
209
210public:
211 OpsLogSocket(CephContext *cct, uint64_t _backlog);
a4b75251 212};
7c673cae 213
a4b75251 214class OpsLogRados : public OpsLogSink {
20effc67
TL
215 // main()'s Store pointer as a reference, possibly modified by RGWRealmReloader
216 rgw::sal::Store* const& store;
217
a4b75251 218public:
20effc67 219 OpsLogRados(rgw::sal::Store* const& store);
a4b75251 220 int log(struct req_state* s, struct rgw_log_entry& entry) override;
7c673cae
FG
221};
222
223class RGWREST;
224
a4b75251
TL
225int rgw_log_op(RGWREST* const rest, struct req_state* s,
226 const std::string& op_name, OpsLogSink* olog);
20effc67 227void rgw_log_usage_init(CephContext* cct, rgw::sal::Store* store);
7c673cae
FG
228void rgw_log_usage_finalize();
229void rgw_format_ops_log_entry(struct rgw_log_entry& entry,
9f95a23c 230 ceph::Formatter *formatter);
7c673cae
FG
231
232#endif /* CEPH_RGW_LOG_H */
233