Files
git.stella-ops.org/src/AdvisoryAI/StellaOps.AdvisoryAI/UnifiedSearch/UnifiedSearchTelemetry.cs

70 lines
2.3 KiB
C#

using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
namespace StellaOps.AdvisoryAI.UnifiedSearch;
public sealed record UnifiedSearchTelemetryEvent(
string Tenant,
string QueryHash,
string Intent,
int ResultCount,
long DurationMs,
bool UsedVector,
IReadOnlyDictionary<string, double> DomainWeights,
IReadOnlyList<string> TopDomains);
public interface IUnifiedSearchTelemetrySink
{
void Record(UnifiedSearchTelemetryEvent telemetryEvent);
}
internal sealed class LoggingUnifiedSearchTelemetrySink : IUnifiedSearchTelemetrySink
{
private readonly ILogger<LoggingUnifiedSearchTelemetrySink> _logger;
public LoggingUnifiedSearchTelemetrySink(ILogger<LoggingUnifiedSearchTelemetrySink> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public void Record(UnifiedSearchTelemetryEvent telemetryEvent)
{
ArgumentNullException.ThrowIfNull(telemetryEvent);
var weights = string.Join(
",",
telemetryEvent.DomainWeights
.OrderBy(static pair => pair.Key, StringComparer.Ordinal)
.Select(static pair => $"{pair.Key}:{pair.Value.ToString("F3", CultureInfo.InvariantCulture)}"));
var topDomains = telemetryEvent.TopDomains.Count == 0
? "-"
: string.Join(",", telemetryEvent.TopDomains.OrderBy(static value => value, StringComparer.Ordinal));
_logger.LogInformation(
"unified_search telemetry tenant={Tenant} query_hash={QueryHash} intent={Intent} results={ResultCount} duration_ms={DurationMs} used_vector={UsedVector} top_domains={TopDomains} weights={Weights}",
telemetryEvent.Tenant,
telemetryEvent.QueryHash,
telemetryEvent.Intent,
telemetryEvent.ResultCount,
telemetryEvent.DurationMs,
telemetryEvent.UsedVector,
topDomains,
weights);
}
}
internal static class UnifiedSearchTelemetryHash
{
public static string HashQuery(string query)
{
ArgumentNullException.ThrowIfNull(query);
var bytes = Encoding.UTF8.GetBytes(query);
var hash = SHA256.HashData(bytes);
return Convert.ToHexString(hash).ToLowerInvariant();
}
}