getQueryProfileReport function

String getQueryProfileReport()

Get the full profiling report.

Implementation

String getQueryProfileReport() {
  if (!_queryProfilerEnabled) {
    return 'Query profiling not enabled (set MAGE_PROFILE_QUERY=1)';
  }

  if (_checkpointTimes.isEmpty) {
    return 'No query profiling checkpoints recorded';
  }

  final lines = <String>[];
  lines.add('=' * 80);
  lines.add('QUERY PROFILING REPORT - Query #$_queryCount');
  lines.add('=' * 80);
  lines.add('');

  final baseline = _baselineTime ?? 0;
  var prevTime = baseline;
  double apiRequestSentTime = 0;
  double firstChunkTime = 0;

  final sortedNames = _checkpointTimes.keys.toList()
    ..sort((a, b) => _checkpointTimes[a]!.compareTo(_checkpointTimes[b]!));

  for (final name in sortedNames) {
    final time = _checkpointTimes[name]!;
    final relativeTime = time - baseline;
    final deltaMs = time - prevTime;
    final warning = _getSlowWarning(deltaMs, name);
    lines.add(
      '${_formatMs(relativeTime).padLeft(10)}ms  +${_formatMs(deltaMs).padLeft(9)}ms  $name$warning',
    );

    if (name == 'query_api_request_sent') apiRequestSentTime = relativeTime;
    if (name == 'query_first_chunk_received') firstChunkTime = relativeTime;

    prevTime = time;
  }

  lines.add('');
  lines.add('-' * 80);

  if (firstChunkTime > 0) {
    final preRequestOverhead = apiRequestSentTime;
    final networkLatency = firstChunkTime - apiRequestSentTime;
    final preRequestPercent = (preRequestOverhead / firstChunkTime * 100)
        .toStringAsFixed(1);
    final networkPercent = (networkLatency / firstChunkTime * 100)
        .toStringAsFixed(1);

    lines.add('Total TTFT: ${_formatMs(firstChunkTime)}ms');
    lines.add(
      '  - Pre-request overhead: ${_formatMs(preRequestOverhead)}ms ($preRequestPercent%)',
    );
    lines.add(
      '  - Network latency: ${_formatMs(networkLatency)}ms ($networkPercent%)',
    );
  } else {
    final totalTime = prevTime - baseline;
    lines.add('Total time: ${_formatMs(totalTime)}ms');
  }

  lines.add(_getPhaseSummary());
  lines.add('=' * 80);

  return lines.join('\n');
}