|
| 1 | +// Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | +// Licensed under the MIT License. |
| 3 | +package com.microsoft.durabletask; |
| 4 | + |
| 5 | +import org.slf4j.Logger; |
| 6 | +import org.slf4j.Marker; |
| 7 | +import org.slf4j.event.Level; |
| 8 | +import org.slf4j.spi.LoggingEventBuilder; |
| 9 | +import org.slf4j.spi.NOPLoggingEventBuilder; |
| 10 | + |
| 11 | +/** |
| 12 | + * An SLF4J {@link Logger} wrapper that suppresses log output during orchestration replay. |
| 13 | + * |
| 14 | + * <p>Traditional logging methods ({@code info}, {@code debug}, etc.) and the SLF4J 2.x fluent API |
| 15 | + * ({@code atInfo()}, {@code atDebug()}, etc.) are both gated on |
| 16 | + * {@link TaskOrchestrationContext#getIsReplaying()}. The {@code isXxxEnabled()} family of methods |
| 17 | + * always passes through to the underlying logger unchanged. |
| 18 | + * |
| 19 | + * <p>This mirrors the {@code ReplaySafeLogger} nested class in the modern .NET |
| 20 | + * {@code TaskOrchestrationContext}. |
| 21 | + */ |
| 22 | +final class ReplaySafeLogger implements Logger { |
| 23 | + |
| 24 | + private final TaskOrchestrationContext context; |
| 25 | + private final Logger inner; |
| 26 | + |
| 27 | + ReplaySafeLogger(TaskOrchestrationContext context, Logger inner) { |
| 28 | + Helpers.throwIfArgumentNull(context, "context"); |
| 29 | + Helpers.throwIfArgumentNull(inner, "inner"); |
| 30 | + this.context = context; |
| 31 | + this.inner = inner; |
| 32 | + } |
| 33 | + |
| 34 | + // ----------------------------------------------------------------------- |
| 35 | + // getName — always pass through |
| 36 | + // ----------------------------------------------------------------------- |
| 37 | + |
| 38 | + @Override |
| 39 | + public String getName() { |
| 40 | + return inner.getName(); |
| 41 | + } |
| 42 | + |
| 43 | + // ----------------------------------------------------------------------- |
| 44 | + // isXxxEnabled — always pass through (matches .NET IsEnabled behavior) |
| 45 | + // ----------------------------------------------------------------------- |
| 46 | + |
| 47 | + @Override public boolean isTraceEnabled() { return inner.isTraceEnabled(); } |
| 48 | + @Override public boolean isTraceEnabled(Marker marker) { return inner.isTraceEnabled(marker); } |
| 49 | + @Override public boolean isDebugEnabled() { return inner.isDebugEnabled(); } |
| 50 | + @Override public boolean isDebugEnabled(Marker marker) { return inner.isDebugEnabled(marker); } |
| 51 | + @Override public boolean isInfoEnabled() { return inner.isInfoEnabled(); } |
| 52 | + @Override public boolean isInfoEnabled(Marker marker) { return inner.isInfoEnabled(marker); } |
| 53 | + @Override public boolean isWarnEnabled() { return inner.isWarnEnabled(); } |
| 54 | + @Override public boolean isWarnEnabled(Marker marker) { return inner.isWarnEnabled(marker); } |
| 55 | + @Override public boolean isErrorEnabled() { return inner.isErrorEnabled(); } |
| 56 | + @Override public boolean isErrorEnabled(Marker marker) { return inner.isErrorEnabled(marker); } |
| 57 | + |
| 58 | + // ----------------------------------------------------------------------- |
| 59 | + // SLF4J 2.x fluent API — gate via makeLoggingEventBuilder |
| 60 | + // |
| 61 | + // atInfo(), atDebug(), atWarn(), atError(), atTrace(), atLevel() are |
| 62 | + // default methods on Logger that all delegate to makeLoggingEventBuilder(). |
| 63 | + // They bypass the traditional info/debug/warn/error/trace methods |
| 64 | + // entirely, so we MUST override this single entry point to prevent |
| 65 | + // fluent-API calls from escaping replay safety. |
| 66 | + // ----------------------------------------------------------------------- |
| 67 | + |
| 68 | + @Override |
| 69 | + public LoggingEventBuilder makeLoggingEventBuilder(Level level) { |
| 70 | + if (context.getIsReplaying()) { |
| 71 | + return NOPLoggingEventBuilder.singleton(); |
| 72 | + } |
| 73 | + return inner.makeLoggingEventBuilder(level); |
| 74 | + } |
| 75 | + |
| 76 | + // ----------------------------------------------------------------------- |
| 77 | + // trace — gated on !isReplaying |
| 78 | + // ----------------------------------------------------------------------- |
| 79 | + |
| 80 | + @Override public void trace(String msg) { if (!context.getIsReplaying()) inner.trace(msg); } |
| 81 | + @Override public void trace(String format, Object arg) { if (!context.getIsReplaying()) inner.trace(format, arg); } |
| 82 | + @Override public void trace(String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.trace(format, arg1, arg2); } |
| 83 | + @Override public void trace(String format, Object... arguments) { if (!context.getIsReplaying()) inner.trace(format, arguments); } |
| 84 | + @Override public void trace(String msg, Throwable t) { if (!context.getIsReplaying()) inner.trace(msg, t); } |
| 85 | + @Override public void trace(Marker marker, String msg) { if (!context.getIsReplaying()) inner.trace(marker, msg); } |
| 86 | + @Override public void trace(Marker marker, String format, Object arg) { if (!context.getIsReplaying()) inner.trace(marker, format, arg); } |
| 87 | + @Override public void trace(Marker marker, String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.trace(marker, format, arg1, arg2); } |
| 88 | + @Override public void trace(Marker marker, String format, Object... argArray) { if (!context.getIsReplaying()) inner.trace(marker, format, argArray); } |
| 89 | + @Override public void trace(Marker marker, String msg, Throwable t) { if (!context.getIsReplaying()) inner.trace(marker, msg, t); } |
| 90 | + |
| 91 | + // ----------------------------------------------------------------------- |
| 92 | + // debug — gated on !isReplaying |
| 93 | + // ----------------------------------------------------------------------- |
| 94 | + |
| 95 | + @Override public void debug(String msg) { if (!context.getIsReplaying()) inner.debug(msg); } |
| 96 | + @Override public void debug(String format, Object arg) { if (!context.getIsReplaying()) inner.debug(format, arg); } |
| 97 | + @Override public void debug(String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.debug(format, arg1, arg2); } |
| 98 | + @Override public void debug(String format, Object... arguments) { if (!context.getIsReplaying()) inner.debug(format, arguments); } |
| 99 | + @Override public void debug(String msg, Throwable t) { if (!context.getIsReplaying()) inner.debug(msg, t); } |
| 100 | + @Override public void debug(Marker marker, String msg) { if (!context.getIsReplaying()) inner.debug(marker, msg); } |
| 101 | + @Override public void debug(Marker marker, String format, Object arg) { if (!context.getIsReplaying()) inner.debug(marker, format, arg); } |
| 102 | + @Override public void debug(Marker marker, String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.debug(marker, format, arg1, arg2); } |
| 103 | + @Override public void debug(Marker marker, String format, Object... arguments) { if (!context.getIsReplaying()) inner.debug(marker, format, arguments); } |
| 104 | + @Override public void debug(Marker marker, String msg, Throwable t) { if (!context.getIsReplaying()) inner.debug(marker, msg, t); } |
| 105 | + |
| 106 | + // ----------------------------------------------------------------------- |
| 107 | + // info — gated on !isReplaying |
| 108 | + // ----------------------------------------------------------------------- |
| 109 | + |
| 110 | + @Override public void info(String msg) { if (!context.getIsReplaying()) inner.info(msg); } |
| 111 | + @Override public void info(String format, Object arg) { if (!context.getIsReplaying()) inner.info(format, arg); } |
| 112 | + @Override public void info(String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.info(format, arg1, arg2); } |
| 113 | + @Override public void info(String format, Object... arguments) { if (!context.getIsReplaying()) inner.info(format, arguments); } |
| 114 | + @Override public void info(String msg, Throwable t) { if (!context.getIsReplaying()) inner.info(msg, t); } |
| 115 | + @Override public void info(Marker marker, String msg) { if (!context.getIsReplaying()) inner.info(marker, msg); } |
| 116 | + @Override public void info(Marker marker, String format, Object arg) { if (!context.getIsReplaying()) inner.info(marker, format, arg); } |
| 117 | + @Override public void info(Marker marker, String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.info(marker, format, arg1, arg2); } |
| 118 | + @Override public void info(Marker marker, String format, Object... arguments) { if (!context.getIsReplaying()) inner.info(marker, format, arguments); } |
| 119 | + @Override public void info(Marker marker, String msg, Throwable t) { if (!context.getIsReplaying()) inner.info(marker, msg, t); } |
| 120 | + |
| 121 | + // ----------------------------------------------------------------------- |
| 122 | + // warn — gated on !isReplaying |
| 123 | + // ----------------------------------------------------------------------- |
| 124 | + |
| 125 | + @Override public void warn(String msg) { if (!context.getIsReplaying()) inner.warn(msg); } |
| 126 | + @Override public void warn(String format, Object arg) { if (!context.getIsReplaying()) inner.warn(format, arg); } |
| 127 | + @Override public void warn(String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.warn(format, arg1, arg2); } |
| 128 | + @Override public void warn(String format, Object... arguments) { if (!context.getIsReplaying()) inner.warn(format, arguments); } |
| 129 | + @Override public void warn(String msg, Throwable t) { if (!context.getIsReplaying()) inner.warn(msg, t); } |
| 130 | + @Override public void warn(Marker marker, String msg) { if (!context.getIsReplaying()) inner.warn(marker, msg); } |
| 131 | + @Override public void warn(Marker marker, String format, Object arg) { if (!context.getIsReplaying()) inner.warn(marker, format, arg); } |
| 132 | + @Override public void warn(Marker marker, String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.warn(marker, format, arg1, arg2); } |
| 133 | + @Override public void warn(Marker marker, String format, Object... arguments) { if (!context.getIsReplaying()) inner.warn(marker, format, arguments); } |
| 134 | + @Override public void warn(Marker marker, String msg, Throwable t) { if (!context.getIsReplaying()) inner.warn(marker, msg, t); } |
| 135 | + |
| 136 | + // ----------------------------------------------------------------------- |
| 137 | + // error — gated on !isReplaying |
| 138 | + // ----------------------------------------------------------------------- |
| 139 | + |
| 140 | + @Override public void error(String msg) { if (!context.getIsReplaying()) inner.error(msg); } |
| 141 | + @Override public void error(String format, Object arg) { if (!context.getIsReplaying()) inner.error(format, arg); } |
| 142 | + @Override public void error(String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.error(format, arg1, arg2); } |
| 143 | + @Override public void error(String format, Object... arguments) { if (!context.getIsReplaying()) inner.error(format, arguments); } |
| 144 | + @Override public void error(String msg, Throwable t) { if (!context.getIsReplaying()) inner.error(msg, t); } |
| 145 | + @Override public void error(Marker marker, String msg) { if (!context.getIsReplaying()) inner.error(marker, msg); } |
| 146 | + @Override public void error(Marker marker, String format, Object arg) { if (!context.getIsReplaying()) inner.error(marker, format, arg); } |
| 147 | + @Override public void error(Marker marker, String format, Object arg1, Object arg2) { if (!context.getIsReplaying()) inner.error(marker, format, arg1, arg2); } |
| 148 | + @Override public void error(Marker marker, String format, Object... arguments) { if (!context.getIsReplaying()) inner.error(marker, format, arguments); } |
| 149 | + @Override public void error(Marker marker, String msg, Throwable t) { if (!context.getIsReplaying()) inner.error(marker, msg, t); } |
| 150 | +} |
0 commit comments