1use crate::{BaseLogEntry, LogRecord, ObjectVersion};
16use chrono::{DateTime, Utc};
17use serde::{Deserialize, Serialize};
18use serde_json::Value;
19use std::collections::HashMap;
20
21#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
76pub struct ApiDetails {
77 #[serde(rename = "name", skip_serializing_if = "Option::is_none")]
78 pub name: Option<String>,
79 #[serde(rename = "bucket", skip_serializing_if = "Option::is_none")]
80 pub bucket: Option<String>,
81 #[serde(rename = "object", skip_serializing_if = "Option::is_none")]
82 pub object: Option<String>,
83 #[serde(rename = "objects", skip_serializing_if = "Vec::is_empty", default)]
84 pub objects: Vec<ObjectVersion>,
85 #[serde(rename = "status", skip_serializing_if = "Option::is_none")]
86 pub status: Option<String>,
87 #[serde(rename = "statusCode", skip_serializing_if = "Option::is_none")]
88 pub status_code: Option<i32>,
89 #[serde(rename = "rx")]
90 pub input_bytes: i64,
91 #[serde(rename = "tx")]
92 pub output_bytes: i64,
93 #[serde(rename = "txHeaders", skip_serializing_if = "Option::is_none")]
94 pub header_bytes: Option<i64>,
95 #[serde(rename = "timeToFirstByte", skip_serializing_if = "Option::is_none")]
96 pub time_to_first_byte: Option<String>,
97 #[serde(rename = "timeToFirstByteInNS", skip_serializing_if = "Option::is_none")]
98 pub time_to_first_byte_in_ns: Option<String>,
99 #[serde(rename = "timeToResponse", skip_serializing_if = "Option::is_none")]
100 pub time_to_response: Option<String>,
101 #[serde(rename = "timeToResponseInNS", skip_serializing_if = "Option::is_none")]
102 pub time_to_response_in_ns: Option<String>,
103}
104
105impl ApiDetails {
106 pub fn new() -> Self {
108 ApiDetails {
109 name: None,
110 bucket: None,
111 object: None,
112 objects: Vec::new(),
113 status: None,
114 status_code: None,
115 input_bytes: 0,
116 output_bytes: 0,
117 header_bytes: None,
118 time_to_first_byte: None,
119 time_to_first_byte_in_ns: None,
120 time_to_response: None,
121 time_to_response_in_ns: None,
122 }
123 }
124
125 pub fn set_name(mut self, name: Option<String>) -> Self {
127 self.name = name;
128 self
129 }
130
131 pub fn set_bucket(mut self, bucket: Option<String>) -> Self {
133 self.bucket = bucket;
134 self
135 }
136
137 pub fn set_object(mut self, object: Option<String>) -> Self {
139 self.object = object;
140 self
141 }
142
143 pub fn set_objects(mut self, objects: Vec<ObjectVersion>) -> Self {
145 self.objects = objects;
146 self
147 }
148
149 pub fn set_status(mut self, status: Option<String>) -> Self {
151 self.status = status;
152 self
153 }
154
155 pub fn set_status_code(mut self, status_code: Option<i32>) -> Self {
157 self.status_code = status_code;
158 self
159 }
160
161 pub fn set_input_bytes(mut self, input_bytes: i64) -> Self {
163 self.input_bytes = input_bytes;
164 self
165 }
166
167 pub fn set_output_bytes(mut self, output_bytes: i64) -> Self {
169 self.output_bytes = output_bytes;
170 self
171 }
172
173 pub fn set_header_bytes(mut self, header_bytes: Option<i64>) -> Self {
175 self.header_bytes = header_bytes;
176 self
177 }
178
179 pub fn set_time_to_first_byte(mut self, time_to_first_byte: Option<String>) -> Self {
181 self.time_to_first_byte = time_to_first_byte;
182 self
183 }
184
185 pub fn set_time_to_first_byte_in_ns(mut self, time_to_first_byte_in_ns: Option<String>) -> Self {
187 self.time_to_first_byte_in_ns = time_to_first_byte_in_ns;
188 self
189 }
190
191 pub fn set_time_to_response(mut self, time_to_response: Option<String>) -> Self {
193 self.time_to_response = time_to_response;
194 self
195 }
196
197 pub fn set_time_to_response_in_ns(mut self, time_to_response_in_ns: Option<String>) -> Self {
199 self.time_to_response_in_ns = time_to_response_in_ns;
200 self
201 }
202}
203
204#[derive(Debug, Serialize, Deserialize, Clone, Default)]
271pub struct AuditLogEntry {
272 #[serde(flatten)]
273 pub base: BaseLogEntry,
274 pub version: String,
275 #[serde(rename = "deploymentid", skip_serializing_if = "Option::is_none")]
276 pub deployment_id: Option<String>,
277 pub event: String,
278 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
280 pub entry_type: Option<String>,
281 pub api: ApiDetails,
282 #[serde(rename = "remotehost", skip_serializing_if = "Option::is_none")]
283 pub remote_host: Option<String>,
284 #[serde(rename = "userAgent", skip_serializing_if = "Option::is_none")]
285 pub user_agent: Option<String>,
286 #[serde(rename = "requestPath", skip_serializing_if = "Option::is_none")]
287 pub req_path: Option<String>,
288 #[serde(rename = "requestHost", skip_serializing_if = "Option::is_none")]
289 pub req_host: Option<String>,
290 #[serde(rename = "requestClaims", skip_serializing_if = "Option::is_none")]
291 pub req_claims: Option<HashMap<String, Value>>,
292 #[serde(rename = "requestQuery", skip_serializing_if = "Option::is_none")]
293 pub req_query: Option<HashMap<String, String>>,
294 #[serde(rename = "requestHeader", skip_serializing_if = "Option::is_none")]
295 pub req_header: Option<HashMap<String, String>>,
296 #[serde(rename = "responseHeader", skip_serializing_if = "Option::is_none")]
297 pub resp_header: Option<HashMap<String, String>>,
298 #[serde(rename = "accessKey", skip_serializing_if = "Option::is_none")]
299 pub access_key: Option<String>,
300 #[serde(rename = "parentUser", skip_serializing_if = "Option::is_none")]
301 pub parent_user: Option<String>,
302 #[serde(rename = "error", skip_serializing_if = "Option::is_none")]
303 pub error: Option<String>,
304}
305
306impl AuditLogEntry {
307 pub fn new() -> Self {
309 AuditLogEntry {
310 base: BaseLogEntry::new(),
311 version: String::new(),
312 deployment_id: None,
313 event: String::new(),
314 entry_type: None,
315 api: ApiDetails::new(),
316 remote_host: None,
317 user_agent: None,
318 req_path: None,
319 req_host: None,
320 req_claims: None,
321 req_query: None,
322 req_header: None,
323 resp_header: None,
324 access_key: None,
325 parent_user: None,
326 error: None,
327 }
328 }
329
330 pub fn new_with_values(version: String, time: DateTime<Utc>, event: String, api: ApiDetails) -> Self {
332 let mut base = BaseLogEntry::new();
333 base.timestamp = time;
334
335 AuditLogEntry {
336 base,
337 version,
338 deployment_id: None,
339 event,
340 entry_type: None,
341 api,
342 remote_host: None,
343 user_agent: None,
344 req_path: None,
345 req_host: None,
346 req_claims: None,
347 req_query: None,
348 req_header: None,
349 resp_header: None,
350 access_key: None,
351 parent_user: None,
352 error: None,
353 }
354 }
355
356 pub fn with_base(mut self, base: BaseLogEntry) -> Self {
358 self.base = base;
359 self
360 }
361
362 pub fn set_version(mut self, version: String) -> Self {
364 self.version = version;
365 self
366 }
367
368 pub fn set_deployment_id(mut self, deployment_id: Option<String>) -> Self {
370 self.deployment_id = deployment_id;
371 self
372 }
373
374 pub fn set_event(mut self, event: String) -> Self {
376 self.event = event;
377 self
378 }
379
380 pub fn set_entry_type(mut self, entry_type: Option<String>) -> Self {
382 self.entry_type = entry_type;
383 self
384 }
385
386 pub fn set_api(mut self, api: ApiDetails) -> Self {
388 self.api = api;
389 self
390 }
391
392 pub fn set_remote_host(mut self, remote_host: Option<String>) -> Self {
394 self.remote_host = remote_host;
395 self
396 }
397
398 pub fn set_user_agent(mut self, user_agent: Option<String>) -> Self {
400 self.user_agent = user_agent;
401 self
402 }
403
404 pub fn set_req_path(mut self, req_path: Option<String>) -> Self {
406 self.req_path = req_path;
407 self
408 }
409
410 pub fn set_req_host(mut self, req_host: Option<String>) -> Self {
412 self.req_host = req_host;
413 self
414 }
415
416 pub fn set_req_claims(mut self, req_claims: Option<HashMap<String, Value>>) -> Self {
418 self.req_claims = req_claims;
419 self
420 }
421
422 pub fn set_req_query(mut self, req_query: Option<HashMap<String, String>>) -> Self {
424 self.req_query = req_query;
425 self
426 }
427
428 pub fn set_req_header(mut self, req_header: Option<HashMap<String, String>>) -> Self {
430 self.req_header = req_header;
431 self
432 }
433
434 pub fn set_resp_header(mut self, resp_header: Option<HashMap<String, String>>) -> Self {
436 self.resp_header = resp_header;
437 self
438 }
439
440 pub fn set_access_key(mut self, access_key: Option<String>) -> Self {
442 self.access_key = access_key;
443 self
444 }
445
446 pub fn set_parent_user(mut self, parent_user: Option<String>) -> Self {
448 self.parent_user = parent_user;
449 self
450 }
451
452 pub fn set_error(mut self, error: Option<String>) -> Self {
454 self.error = error;
455 self
456 }
457}
458
459impl LogRecord for AuditLogEntry {
460 fn to_json(&self) -> String {
461 serde_json::to_string(self).unwrap_or_else(|_| String::from("{}"))
462 }
463
464 fn get_timestamp(&self) -> DateTime<Utc> {
465 self.base.timestamp
466 }
467}