| 513 | } |
| 514 | if (request.body.empty() && request.body_stream == nullptr) { |
| 515 | return; |
| 516 | } |
| 517 | std::ostringstream out; |
| 518 | out << "[REQUEST_BODY_SKIPPED] " << request.method << " " << request.path |
| 519 | << " content_type=" << json_quote(request_content_type(request)); |
| 520 | if (request.body_stream != nullptr) { |
| 521 | out << " body=stream"; |
| 522 | } else { |
| 523 | out << " body_bytes=" << request.body.size(); |
| 524 | } |
| 525 | if (!request.query.empty()) { |
| 526 | out << " query=" << json_quote(request.query); |
| 527 | } |
| 528 | engine::debug::log_message(out.str()); |
| 529 | } |
| 530 | |
| 531 | void log_multipart_request_summary_if_enabled( |
| 532 | const ServerConfig & config, |
| 533 | const std::vector<MultipartPart> & parts) { |
| 534 | if (!config.log_request_body || !engine::debug::log_enabled()) { |
| 535 | return; |
| 536 | } |
| 537 | for (const auto & part : parts) { |
| 538 | if (part.filename.empty()) { |
| 539 | continue; |
| 540 | } |
| 541 | std::ostringstream out; |
| 542 | out << "[REQUEST_BODY_SKIPPED] multipart_file" |
| 543 | << " field=" << json_quote(part.name) |
| 544 | << " filename=" << json_quote(part.filename) |
| 545 | << " bytes=" << part.data.size(); |
| 546 | engine::debug::log_message(out.str()); |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | double elapsed_ms(Clock::time_point started) { |
| 551 | return std::chrono::duration<double, std::milli>(Clock::now() - started).count(); |
| 552 | } |
| 553 | |
| 554 | double audio_duration_ms(const engine::runtime::AudioBuffer & audio) { |
| 555 | if (audio.sample_rate <= 0 || audio.channels <= 0) { |
| 556 | return 0.0; |
| 557 | } |
| 558 | return 1000.0 * static_cast<double>(audio.samples.size()) / |
| 559 | static_cast<double>(audio.sample_rate * audio.channels); |
| 560 | } |
| 561 | |
| 562 | double audio_rtf(double wall_ms, double duration_ms) { |
| 563 | return duration_ms > 0.0 ? wall_ms / duration_ms : 0.0; |
| 564 | } |
| 565 | |
| 566 | std::string timing_json(double wall_ms) { |
| 567 | std::ostringstream out; |
| 568 | out << "{\"wall_ms\":" << wall_ms << "}"; |
| 569 | return out.str(); |
| 570 | } |
| 571 | |
| 572 | std::string timing_json(double wall_ms, const engine::runtime::AudioBuffer & audio) { |
nothing calls this directly
no test coverage detected