public void OperationFinished(string message, string operationName, string componentName, ResultBase result, TimeSpan duration, Severity successSeverity, OperationKind kind) { // Severity level for non-successful case is computed in the following way: // CriticalFailures -> Error // Non-critical errors during initialization -> Warning // Non-critical errors in all the other operations -> Info var severity = successSeverity; if (!result.Succeeded) { severity = result.IsCriticalFailure ? Severity.Error : (kind == OperationKind.Startup ? Severity.Warning : Severity.Info); } bool messageWasTraced = false; // The Logger instance may implement both IOperationLogger and IStructuredLogger // (this is actually the case right now for the new logging infrastructure). // And to get correct behavior in this case we need to check IStructuredLogger // first because that kind of logger does two things: // 1. Traces the operation and // 2. Emit metrics. // But other IOperationLogger implementation just trace the metrics and a text racing should be done separately. if (Logger is IStructuredLogger structuredLogger) { // Note, that 'message' here is a plain message from the client // without correlation id. var operationResult = new OperationResult(message, operationName, componentName, result.GetStatus(), duration, kind, result.Exception, _idAsString, severity); structuredLogger.LogOperationFinished(operationResult); messageWasTraced = true; } else if (Logger is IOperationLogger operationLogger) { var operationResult = new OperationResult(message, operationName, componentName, result.GetStatus(), duration, kind, result.Exception, _idAsString, severity); operationLogger.OperationFinished(operationResult); } if (!messageWasTraced) { TraceMessage(severity, message, componentName, operationName); } }