]>
Commit | Line | Data |
---|---|---|
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 |
15 | namespace rgw { namespace sal { |
16 | class Store; | |
17 | } } | |
7c673cae FG |
18 | |
19 | struct 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 | }; |
148 | WRITE_CLASS_ENCODER(rgw_log_entry) | |
149 | ||
a4b75251 TL |
150 | class OpsLogSink { |
151 | public: | |
152 | virtual int log(struct req_state* s, struct rgw_log_entry& entry) = 0; | |
153 | virtual ~OpsLogSink() = default; | |
154 | }; | |
155 | ||
156 | class OpsLogManifold: public OpsLogSink { | |
157 | std::vector<OpsLogSink*> sinks; | |
158 | public: | |
159 | ~OpsLogManifold() override; | |
160 | void add_sink(OpsLogSink* sink); | |
161 | int log(struct req_state* s, struct rgw_log_entry& entry) override; | |
162 | }; | |
163 | ||
164 | class 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 |
169 | protected: |
170 | virtual int log_json(struct req_state* s, bufferlist& bl) = 0; | |
171 | public: | |
172 | JsonOpsLogSink(); | |
173 | ~JsonOpsLogSink() override; | |
174 | int log(struct req_state* s, struct rgw_log_entry& entry) override; | |
175 | }; | |
176 | ||
177 | class 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(); | |
191 | protected: | |
192 | int log_json(struct req_state* s, bufferlist& bl) override; | |
193 | void *entry() override; | |
194 | public: | |
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 | 205 | class OpsLogSocket : public OutputDataSocket, public JsonOpsLogSink { |
7c673cae | 206 | protected: |
a4b75251 | 207 | int log_json(struct req_state* s, bufferlist& bl) override; |
7c673cae FG |
208 | void init_connection(bufferlist& bl) override; |
209 | ||
210 | public: | |
211 | OpsLogSocket(CephContext *cct, uint64_t _backlog); | |
a4b75251 | 212 | }; |
7c673cae | 213 | |
a4b75251 | 214 | class 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 | 218 | public: |
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 | ||
223 | class RGWREST; | |
224 | ||
a4b75251 TL |
225 | int rgw_log_op(RGWREST* const rest, struct req_state* s, |
226 | const std::string& op_name, OpsLogSink* olog); | |
20effc67 | 227 | void rgw_log_usage_init(CephContext* cct, rgw::sal::Store* store); |
7c673cae FG |
228 | void rgw_log_usage_finalize(); |
229 | void 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 |