Skip to content

Commit fb357ba

Browse files
committed
chore: Replaces string interpolation with structured logging
Migrates Redis server endpoint logging from string interpolation to LoggerMessage attributes for better performance and structured logging support. Adds 14 new LoggerMessage methods for server connection lifecycle events including handshake, authentication, configuration, and buffer operations. Uses ServerEndPointLogValue wrapper to ensure consistent server representation in logs while maintaining type safety.
1 parent 265cc12 commit fb357ba

File tree

2 files changed

+99
-14
lines changed

2 files changed

+99
-14
lines changed

src/StackExchange.Redis/LoggerExtensions.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,89 @@ internal static void LogWithThreadPoolStats(this ILogger? log, string message)
403403
EventId = 56,
404404
Message = "...but we did find instead: {DeDottedEndpoint}")]
405405
internal static partial void LogInformationFoundAlternativeEndpoint(this ILogger logger, string deDottedEndpoint);
406+
407+
// ServerEndPoint logging methods
408+
[LoggerMessage(
409+
Level = LogLevel.Information,
410+
EventId = 57,
411+
Message = "{Server}: OnConnectedAsync already connected start")]
412+
internal static partial void LogInformationOnConnectedAsyncAlreadyConnectedStart(this ILogger logger, ServerEndPointLogValue server);
413+
414+
[LoggerMessage(
415+
Level = LogLevel.Information,
416+
EventId = 58,
417+
Message = "{Server}: OnConnectedAsync already connected end")]
418+
internal static partial void LogInformationOnConnectedAsyncAlreadyConnectedEnd(this ILogger logger, ServerEndPointLogValue server);
419+
420+
[LoggerMessage(
421+
Level = LogLevel.Information,
422+
EventId = 59,
423+
Message = "{Server}: OnConnectedAsync init (State={ConnectionState})")]
424+
internal static partial void LogInformationOnConnectedAsyncInit(this ILogger logger, ServerEndPointLogValue server, PhysicalBridge.State? connectionState);
425+
426+
[LoggerMessage(
427+
Level = LogLevel.Information,
428+
EventId = 60,
429+
Message = "{Server}: OnConnectedAsync completed ({Result})")]
430+
internal static partial void LogInformationOnConnectedAsyncCompleted(this ILogger logger, ServerEndPointLogValue server, string result);
431+
432+
[LoggerMessage(
433+
Level = LogLevel.Information,
434+
EventId = 61,
435+
Message = "{Server}: Auto-configuring...")]
436+
internal static partial void LogInformationAutoConfiguring(this ILogger logger, ServerEndPointLogValue server);
437+
438+
[LoggerMessage(
439+
Level = LogLevel.Information,
440+
EventId = 62,
441+
Message = "{EndPoint}: Requesting tie-break (Key=\"{TieBreakerKey}\")...")]
442+
internal static partial void LogInformationRequestingTieBreak(this ILogger logger, EndPointLogValue endPoint, string tieBreakerKey);
443+
444+
[LoggerMessage(
445+
Level = LogLevel.Information,
446+
EventId = 63,
447+
Message = "{Server}: Server handshake")]
448+
internal static partial void LogInformationServerHandshake(this ILogger logger, ServerEndPointLogValue server);
449+
450+
[LoggerMessage(
451+
Level = LogLevel.Information,
452+
EventId = 64,
453+
Message = "{Server}: Authenticating via HELLO")]
454+
internal static partial void LogInformationAuthenticatingViaHello(this ILogger logger, ServerEndPointLogValue server);
455+
456+
[LoggerMessage(
457+
Level = LogLevel.Information,
458+
EventId = 65,
459+
Message = "{Server}: Authenticating (user/password)")]
460+
internal static partial void LogInformationAuthenticatingUserPassword(this ILogger logger, ServerEndPointLogValue server);
461+
462+
[LoggerMessage(
463+
Level = LogLevel.Information,
464+
EventId = 66,
465+
Message = "{Server}: Authenticating (password)")]
466+
internal static partial void LogInformationAuthenticatingPassword(this ILogger logger, ServerEndPointLogValue server);
467+
468+
[LoggerMessage(
469+
Level = LogLevel.Information,
470+
EventId = 67,
471+
Message = "{Server}: Setting client name: {ClientName}")]
472+
internal static partial void LogInformationSettingClientName(this ILogger logger, ServerEndPointLogValue server, string clientName);
473+
474+
[LoggerMessage(
475+
Level = LogLevel.Information,
476+
EventId = 68,
477+
Message = "{Server}: Setting client lib/ver")]
478+
internal static partial void LogInformationSettingClientLibVer(this ILogger logger, ServerEndPointLogValue server);
479+
480+
[LoggerMessage(
481+
Level = LogLevel.Information,
482+
EventId = 69,
483+
Message = "{Server}: Sending critical tracer (handshake): {CommandAndKey}")]
484+
internal static partial void LogInformationSendingCriticalTracer(this ILogger logger, ServerEndPointLogValue server, string commandAndKey);
485+
486+
[LoggerMessage(
487+
Level = LogLevel.Information,
488+
EventId = 70,
489+
Message = "{Server}: Flushing outbound buffer")]
490+
internal static partial void LogInformationFlushingOutboundBuffer(this ILogger logger, ServerEndPointLogValue server);
406491
}

src/StackExchange.Redis/ServerEndPoint.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public Task<string> OnConnectedAsync(ILogger? log = null, bool sendTracerIfConne
116116
{
117117
async Task<string> IfConnectedAsync(ILogger? log, bool sendTracerIfConnected, bool autoConfigureIfConnected)
118118
{
119-
log?.LogInformation($"{Format.ToString(this)}: OnConnectedAsync already connected start");
119+
log?.LogInformationOnConnectedAsyncAlreadyConnectedStart(new(this));
120120
if (autoConfigureIfConnected)
121121
{
122122
await AutoConfigureAsync(null, log).ForAwait();
@@ -125,15 +125,15 @@ async Task<string> IfConnectedAsync(ILogger? log, bool sendTracerIfConnected, bo
125125
{
126126
await SendTracerAsync(log).ForAwait();
127127
}
128-
log?.LogInformation($"{Format.ToString(this)}: OnConnectedAsync already connected end");
128+
log?.LogInformationOnConnectedAsyncAlreadyConnectedEnd(new(this));
129129
return "Already connected";
130130
}
131131

132132
if (!IsConnected)
133133
{
134-
log?.LogInformation($"{Format.ToString(this)}: OnConnectedAsync init (State={interactive?.ConnectionState})");
134+
log?.LogInformationOnConnectedAsyncInit(new(this), interactive?.ConnectionState);
135135
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
136-
_ = tcs.Task.ContinueWith(t => log?.LogInformation($"{Format.ToString(this)}: OnConnectedAsync completed ({t.Result})"));
136+
_ = tcs.Task.ContinueWith(t => log?.LogInformationOnConnectedAsyncCompleted(new(this), t.Result));
137137
lock (_pendingConnectionMonitors)
138138
{
139139
_pendingConnectionMonitors.Add(tcs);
@@ -383,7 +383,7 @@ internal async Task AutoConfigureAsync(PhysicalConnection? connection, ILogger?
383383
return;
384384
}
385385

386-
log?.LogInformation($"{Format.ToString(this)}: Auto-configuring...");
386+
log?.LogInformationAutoConfiguring(new(this));
387387

388388
var commandMap = Multiplexer.CommandMap;
389389
const CommandFlags flags = CommandFlags.FireAndForget | CommandFlags.NoRedirect;
@@ -458,7 +458,7 @@ internal async Task AutoConfigureAsync(PhysicalConnection? connection, ILogger?
458458
// But if GETs are disabled on this, do not fail the connection - we just don't get tiebreaker benefits
459459
if (Multiplexer.RawConfig.TryGetTieBreaker(out var tieBreakerKey) && Multiplexer.CommandMap.IsAvailable(RedisCommand.GET))
460460
{
461-
log?.LogInformation($"{Format.ToString(EndPoint)}: Requesting tie-break (Key=\"{tieBreakerKey}\")...");
461+
log?.LogInformationRequestingTieBreak(new LoggerExtensions.EndPointLogValue(EndPoint), tieBreakerKey.ToString());
462462
msg = Message.Create(0, flags, RedisCommand.GET, tieBreakerKey);
463463
msg.SetInternalCall();
464464
msg = LoggingMessage.Create(log, msg);
@@ -929,7 +929,7 @@ internal ValueTask WriteDirectOrQueueFireAndForgetAsync<T>(PhysicalConnection? c
929929

930930
private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
931931
{
932-
log?.LogInformation($"{Format.ToString(this)}: Server handshake");
932+
log?.LogInformationServerHandshake(new(this));
933933
if (connection == null)
934934
{
935935
Multiplexer.Trace("No connection!?");
@@ -979,7 +979,7 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
979979
ResultProcessor<bool>? autoConfig = null;
980980
if (Multiplexer.RawConfig.TryResp3()) // note this includes an availability check on HELLO
981981
{
982-
log?.LogInformation($"{Format.ToString(this)}: Authenticating via HELLO");
982+
log?.LogInformationAuthenticatingViaHello(new(this));
983983
var hello = Message.CreateHello(3, user, password, clientName, CommandFlags.FireAndForget);
984984
hello.SetInternalCall();
985985
await WriteDirectOrQueueFireAndForgetAsync(connection, hello, autoConfig ??= ResultProcessor.AutoConfigureProcessor.Create(log)).ForAwait();
@@ -997,14 +997,14 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
997997
// and: we're pipelined here, so... meh
998998
if (!string.IsNullOrWhiteSpace(user) && Multiplexer.CommandMap.IsAvailable(RedisCommand.AUTH))
999999
{
1000-
log?.LogInformation($"{Format.ToString(this)}: Authenticating (user/password)");
1000+
log?.LogInformationAuthenticatingUserPassword(new(this));
10011001
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.AUTH, (RedisValue)user, (RedisValue)password);
10021002
msg.SetInternalCall();
10031003
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
10041004
}
10051005
else if (!string.IsNullOrWhiteSpace(password) && Multiplexer.CommandMap.IsAvailable(RedisCommand.AUTH))
10061006
{
1007-
log?.LogInformation($"{Format.ToString(this)}: Authenticating (password)");
1007+
log?.LogInformationAuthenticatingPassword(new(this));
10081008
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.AUTH, (RedisValue)password);
10091009
msg.SetInternalCall();
10101010
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
@@ -1014,7 +1014,7 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
10141014
{
10151015
if (!string.IsNullOrWhiteSpace(clientName))
10161016
{
1017-
log?.LogInformation($"{Format.ToString(this)}: Setting client name: {clientName}");
1017+
log?.LogInformationSettingClientName(new(this), clientName);
10181018
msg = Message.Create(-1, CommandFlags.FireAndForget, RedisCommand.CLIENT, RedisLiterals.SETNAME, (RedisValue)clientName);
10191019
msg.SetInternalCall();
10201020
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.DemandOK).ForAwait();
@@ -1024,7 +1024,7 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
10241024
{
10251025
// note that this is a relatively new feature, but usually we won't know the
10261026
// server version, so we will use this speculatively and hope for the best
1027-
log?.LogInformation($"{Format.ToString(this)}: Setting client lib/ver");
1027+
log?.LogInformationSettingClientLibVer(new(this));
10281028

10291029
var libName = Multiplexer.GetFullLibraryName();
10301030
if (!string.IsNullOrWhiteSpace(libName))
@@ -1062,7 +1062,7 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
10621062

10631063
var tracer = GetTracerMessage(true);
10641064
tracer = LoggingMessage.Create(log, tracer);
1065-
log?.LogInformation($"{Format.ToString(this)}: Sending critical tracer (handshake): {tracer.CommandAndKey}");
1065+
log?.LogInformationSendingCriticalTracer(new(this), tracer.CommandAndKey);
10661066
await WriteDirectOrQueueFireAndForgetAsync(connection, tracer, ResultProcessor.EstablishConnection).ForAwait();
10671067

10681068
// Note: this **must** be the last thing on the subscription handshake, because after this
@@ -1077,7 +1077,7 @@ private async Task HandshakeAsync(PhysicalConnection connection, ILogger? log)
10771077
await WriteDirectOrQueueFireAndForgetAsync(connection, msg, ResultProcessor.TrackSubscriptions).ForAwait();
10781078
}
10791079
}
1080-
log?.LogInformation($"{Format.ToString(this)}: Flushing outbound buffer");
1080+
log?.LogInformationFlushingOutboundBuffer(new(this));
10811081
await connection.FlushAsync().ForAwait();
10821082
}
10831083

0 commit comments

Comments
 (0)