Skip to content
← Back to Functions
Code

Query Timing Logger

Logs slow query duration, route, and sanitized query label.

Function signature

ogLogSlowQueryTiming(query_label, duration_ms, context = array(), threshold_ms = 250)

Categories

  • Security

Parameters

query_labelHuman-readable query label.duration_msQuery duration in milliseconds.contextOptional route/user context.threshold_msSlow threshold in milliseconds.

Return value

Public-safe status string returned by the function.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Logs slow query duration, route, and sanitized query label.
 *
 * This function returns a safe log row that the caller may write with the project
 * logger. It does not expose bind parameters or raw secret values.
 *
 * @param string $query_label Human-readable query label.
 * @param float $duration_ms Query duration in milliseconds.
 * @param array $context Optional route/user context.
 * @param int $threshold_ms Slow threshold in milliseconds.
 * @return array Slow-query log row.
 */
function ogLogSlowQueryTiming($query_label, $duration_ms, $context = array(), $threshold_ms = 250) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$query_label = trim((string)$query_label);
	$duration_ms = (float)$duration_ms;
	$threshold_ms = (int)$threshold_ms;
	if ($threshold_ms < 1) {
		$threshold_ms = 250;
	}
	if (!is_array($context)) {
		$context = array();
	}

	if (empty($query_label)) {
		$query_label = 'unnamed_query';
	}

	$safe_label = preg_replace('/(password|token|secret|api[_-]?key)\s*[:=]\s*[^\s,&]+/i', '$1=[redacted]', $query_label);
	$safe_context = array();
	foreach ($context as $key => $value) {
		$key = (string)$key;
		if (preg_match('/password|token|secret|api[_-]?key/i', $key)) {
			$safe_context[$key] = '[redacted]';
		} elseif (is_scalar($value)) {
			$safe_context[$key] = (string)$value;
		}
	}

	$result['success'] = true;
	$result['message'] = 'Query timing log row prepared.';
	$result['data'] = array(
		'query_label' => $safe_label,
		'duration_ms' => $duration_ms,
		'threshold_ms' => $threshold_ms,
		'is_slow' => $duration_ms >= $threshold_ms,
		'context' => $safe_context,
		'created_at' => time()
	);

	return $result;
}