Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/OpenClaw.Connection/ConnectionDiagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ public ConnectionDiagnostics(int capacity = 500, IClock? clock = null)

public void Record(string category, string message, string? detail = null)
{
var evt = new ConnectionDiagnosticEvent(_clock.UtcNow, category, message, detail);
var evt = new ConnectionDiagnosticEvent(
_clock.UtcNow,
TokenSanitizer.SanitizeLogMessage(category),
TokenSanitizer.SanitizeLogMessage(message),
detail is null ? null : TokenSanitizer.SanitizeLogMessage(detail));
lock (_lock)
{
_buffer[_head] = evt;
Expand Down
64 changes: 58 additions & 6 deletions src/OpenClaw.SetupEngine/SetupLogger.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Collections.Concurrent;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using OpenClaw.Shared;

namespace OpenClaw.SetupEngine;

Expand Down Expand Up @@ -84,7 +87,7 @@ private void Write(LogLevel level, string message, object? data = null)
{
if (level < _minLevel) return;

var sanitizedMessage = Sanitize(message);
var sanitizedMessage = NormalizeLogString(Sanitize(message));
var entry = new LogEntry(DateTimeOffset.UtcNow, _runId, level, sanitizedMessage, SanitizeData(data));
_recentEntries.Enqueue(entry);
while (_recentEntries.Count > MaxRecentEntries)
Expand Down Expand Up @@ -125,6 +128,10 @@ private void Write(LogLevel level, string message, object? data = null)
internal static string Sanitize(string input)
{
if (string.IsNullOrEmpty(input)) return input;
input = TokenSanitizer.SanitizeLogMessage(input);
if (input == TokenSanitizer.SanitizerTimeoutSentinel)
return input;

input = PrivateKeyPattern().Replace(input, "[REDACTED-PRIVATE-KEY]");
input = BearerPattern().Replace(input, "$1[REDACTED]");
input = JwtPattern().Replace(input, "[REDACTED-JWT]");
Expand All @@ -140,21 +147,65 @@ internal static string Sanitize(string input)
return null;

if (data is string value)
return Sanitize(value);
return NormalizeLogString(Sanitize(value));

try
{
var json = JsonSerializer.Serialize(data, _jsonOptions);
var sanitized = Sanitize(json);
using var doc = JsonDocument.Parse(sanitized);
return doc.RootElement.Clone();
var node = JsonNode.Parse(sanitized);
return NormalizeJsonNode(node);
}
catch (Exception ex) when (ex is JsonException or NotSupportedException or ArgumentException)
{
return Sanitize(data.ToString() ?? string.Empty);
return NormalizeLogString(Sanitize(data.ToString() ?? string.Empty));
}
}

private static JsonNode? NormalizeJsonNode(JsonNode? node)
{
switch (node)
{
case JsonObject obj:
var normalizedObject = new JsonObject();
foreach (var property in obj)
normalizedObject[property.Key] = NormalizeJsonNode(property.Value);
return normalizedObject;

case JsonArray array:
var normalizedArray = new JsonArray();
for (var i = 0; i < array.Count; i++)
normalizedArray.Add(NormalizeJsonNode(array[i]));
return normalizedArray;

case JsonValue value when value.TryGetValue<string>(out var text):
var normalized = NormalizeLogString(text);
var trimmed = normalized.TrimStart();
if (trimmed.StartsWith('{') || trimmed.StartsWith('['))
{
try
{
return NormalizeJsonNode(JsonNode.Parse(normalized));
}
catch (JsonException)
{
// Keep malformed JSON-shaped text as a flattened string.
}
}

return JsonValue.Create(normalized);

default:
return node?.DeepClone();
}
}

private static string NormalizeLogString(string value) =>
value
.Replace("\r\n", " ", StringComparison.Ordinal)
.Replace('\r', ' ')
.Replace('\n', ' ');

private static string Truncate(string input, int max = 4096)
=> input.Length <= max ? input : input[..max] + $"... [truncated {input.Length - max} chars]";

Expand All @@ -178,7 +229,8 @@ private static string Truncate(string input, int max = 4096)

private static readonly JsonSerializerOptions _jsonOptions = new()
{
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

public void Dispose() => _writer?.Dispose();
Expand Down
Loading
Loading