| 2316 | } |
| 2317 | |
| 2318 | Status ClientRequestState::LogAuditRecord(const Status& query_status) { |
| 2319 | const TExecRequest& request = exec_request(); |
| 2320 | stringstream ss; |
| 2321 | rapidjson::StringBuffer buffer; |
| 2322 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
| 2323 | |
| 2324 | writer.StartObject(); |
| 2325 | // Each log entry is a timestamp mapped to a JSON object |
| 2326 | ss << UnixMillis(); |
| 2327 | writer.String(ss.str().c_str()); |
| 2328 | writer.StartObject(); |
| 2329 | writer.String("query_id"); |
| 2330 | writer.String(PrintId(query_id()).c_str()); |
| 2331 | writer.String("session_id"); |
| 2332 | writer.String(PrintId(session_id()).c_str()); |
| 2333 | writer.String("start_time"); |
| 2334 | writer.String(ToStringFromUnixMicros(start_time_us()).c_str()); |
| 2335 | writer.String("authorization_failure"); |
| 2336 | writer.Bool(Frontend::IsAuthorizationError(query_status)); |
| 2337 | writer.String("status"); |
| 2338 | writer.String(query_status.GetDetail().c_str()); |
| 2339 | writer.String("user"); |
| 2340 | writer.String(effective_user().c_str()); |
| 2341 | writer.String("impersonator"); |
| 2342 | if (do_as_user().empty()) { |
| 2343 | // If there is no do_as_user() is empty, the "impersonator" field should be Null. |
| 2344 | writer.Null(); |
| 2345 | } else { |
| 2346 | // Otherwise, the delegator is the current connected user. |
| 2347 | writer.String(connected_user().c_str()); |
| 2348 | } |
| 2349 | writer.String("statement_type"); |
| 2350 | if (request.stmt_type == TStmtType::DDL) { |
| 2351 | if (request.catalog_op_request.op_type == TCatalogOpType::DDL) { |
| 2352 | writer.String(PrintValue(request.catalog_op_request.ddl_params.ddl_type).c_str()); |
| 2353 | } else { |
| 2354 | writer.String(PrintValue(request.catalog_op_request.op_type).c_str()); |
| 2355 | } |
| 2356 | } else { |
| 2357 | writer.String(PrintValue(request.stmt_type).c_str()); |
| 2358 | } |
| 2359 | writer.String("network_address"); |
| 2360 | writer.String(TNetworkAddressToString( |
| 2361 | session()->network_address).c_str()); |
| 2362 | writer.String("sql_statement"); |
| 2363 | string stmt = replace_all_copy(sql_stmt(), "\n", " "); |
| 2364 | Redact(&stmt); |
| 2365 | writer.String(stmt.c_str()); |
| 2366 | writer.String("catalog_objects"); |
| 2367 | |
| 2368 | writer.StartArray(); |
| 2369 | for (const TAccessEvent& event: request.access_events) { |
| 2370 | writer.StartObject(); |
| 2371 | writer.String("name"); |
| 2372 | writer.String(event.name.c_str()); |
| 2373 | writer.String("object_type"); |
| 2374 | writer.String(PrintValue(event.object_type).c_str()); |
| 2375 | writer.String("privilege"); |
nothing calls this directly
no test coverage detected