Flexible loggers' support through SPI mechanism with name `com.alibaba.csp.sentinel.log.Logger` (#1265)
* There are two types of logger for command center and common modules specified by annotation of `LogTarget`
* Add implementing examples in `sentinel-demo/sentinel-demo-log-logback`
* All implementations should support placeholder '{}'
This commit is contained in:
parent
c1ff9135ee
commit
5f203aa79f
|
|
@ -15,36 +15,77 @@
|
||||||
*/
|
*/
|
||||||
package com.alibaba.csp.sentinel.log;
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
import java.util.logging.Handler;
|
import java.util.Iterator;
|
||||||
import java.util.logging.Level;
|
import java.util.ServiceLoader;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger for command center.
|
* Logger for command center.
|
||||||
*/
|
*/
|
||||||
public class CommandCenterLog extends LogBase {
|
public class CommandCenterLog {
|
||||||
|
private static com.alibaba.csp.sentinel.log.Logger log = null;
|
||||||
private static final Logger heliumRecordLog = Logger.getLogger("cspCommandCenterLog");
|
|
||||||
private static final String FILE_NAME = "command-center.log";
|
|
||||||
private static Handler logHandler = null;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
logHandler = makeLogger(FILE_NAME, heliumRecordLog);
|
ServiceLoader<Logger> load = ServiceLoader.load(Logger.class);
|
||||||
|
Logger logger = null;
|
||||||
|
Iterator<Logger> iterator = load.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Logger next = iterator.next();
|
||||||
|
LogTarget annotation = next.getClass().getAnnotation(LogTarget.class);
|
||||||
|
if (annotation == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String value = annotation.value().name();
|
||||||
|
if (value.equals(LogType.COMMAND_CENTER_LOG.name())) {
|
||||||
|
logger = next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use user implementations.
|
||||||
|
if (logger != null) {
|
||||||
|
log = logger;
|
||||||
|
} else {
|
||||||
|
// Use default implementations.
|
||||||
|
log = new CommandCenterLogLogging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String detail, Object... params) {
|
public static void info(String format, Object... arguments) {
|
||||||
log(heliumRecordLog, logHandler, Level.INFO, detail, params);
|
log.info(format, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String detail, Throwable e) {
|
public static void info(String msg, Throwable e) {
|
||||||
log(heliumRecordLog, logHandler, Level.INFO, detail, e);
|
log.info(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warn(String detail, Object... params) {
|
public static void warn(String format, Object... arguments) {
|
||||||
log(heliumRecordLog, logHandler, Level.WARNING, detail, params);
|
log.warn(format, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warn(String detail, Throwable e) {
|
public static void warn(String msg, Throwable e) {
|
||||||
log(heliumRecordLog, logHandler, Level.WARNING, detail, e);
|
log.warn(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trace(String format, Object... arguments) {
|
||||||
|
log.trace(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trace(String msg, Throwable e) {
|
||||||
|
log.trace(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String format, Object... arguments) {
|
||||||
|
log.debug(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String msg, Throwable e) {
|
||||||
|
log.debug(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String format, Object... arguments) {
|
||||||
|
log.error(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String msg, Throwable e) {
|
||||||
|
log.error(msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default logger implementation.
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public class CommandCenterLogLogging extends LogBase implements com.alibaba.csp.sentinel.log.Logger {
|
||||||
|
private final Logger heliumRecordLog = Logger.getLogger("cspCommandCenterLog");
|
||||||
|
private final String FILE_NAME = "command-center.log";
|
||||||
|
private final Handler logHandler = makeLogger(FILE_NAME, heliumRecordLog);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.INFO, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.INFO, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.WARNING, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.WARNING, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.TRACE, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.TRACE, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.DEBUG, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.DEBUG, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.ERROR, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.ERROR, msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright notice
|
||||||
|
* This code copy from SLF4J which licensed under the MIT License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the results of formatting done by {@link MessageFormatter}.
|
||||||
|
*
|
||||||
|
* @author Joern Huxhorn
|
||||||
|
*/
|
||||||
|
public class FormattingTuple {
|
||||||
|
|
||||||
|
static public FormattingTuple NULL = new FormattingTuple(null);
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
private Throwable throwable;
|
||||||
|
private Object[] argArray;
|
||||||
|
|
||||||
|
public FormattingTuple(String message) {
|
||||||
|
this(message, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormattingTuple(String message, Object[] argArray, Throwable throwable) {
|
||||||
|
this.message = message;
|
||||||
|
this.throwable = throwable;
|
||||||
|
this.argArray = argArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgArray() {
|
||||||
|
return argArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getThrowable() {
|
||||||
|
return throwable;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logging levels
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public class Level extends java.util.logging.Level {
|
||||||
|
private static final String defaultBundle = "sun.util.logging.resources.logging";
|
||||||
|
|
||||||
|
public static final Level ERROR = new Level("ERROR", 1000);
|
||||||
|
public static final Level WARNING = new Level("WARNING", 900);
|
||||||
|
public static final Level INFO = new Level("INFO", 800);
|
||||||
|
public static final Level DEBUG = new Level("DEBUG", 700);
|
||||||
|
public static final Level TRACE = new Level("TRACE", 600);
|
||||||
|
|
||||||
|
protected Level(String name, int value) {
|
||||||
|
super(name, value, defaultBundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -152,11 +152,10 @@ public class LogBase {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoggerUtils.disableOtherHandlers(logger, handler);
|
LoggerUtils.disableOtherHandlers(logger, handler);
|
||||||
if (params.length == 0) {
|
|
||||||
logger.log(level, detail);
|
FormattingTuple formattingTuple = MessageFormatter.arrayFormat(detail, params);
|
||||||
} else {
|
String message = formattingTuple.getMessage();
|
||||||
logger.log(level, detail, params);
|
logger.log(level, message);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void log(Logger logger, Handler handler, Level level, String detail, Throwable throwable) {
|
protected static void log(Logger logger, Handler handler, Level level, String detail, Throwable throwable) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Documented
|
||||||
|
public @interface LogTarget {
|
||||||
|
/**
|
||||||
|
* Returns the kinds of log type.
|
||||||
|
* @return Returns the kinds of log type
|
||||||
|
*/
|
||||||
|
LogType value() default LogType.RECORD_LOG;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum marks log type.
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public enum LogType {
|
||||||
|
COMMAND_CENTER_LOG,
|
||||||
|
RECORD_LOG,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide logger SPI interface.
|
||||||
|
* The default implementation is {@link java.util.logging}.
|
||||||
|
*
|
||||||
|
* Notice, the placeholder only supports the most popular placeholder convention (slf4j).
|
||||||
|
* So, if you're not using slf4j, you should create adapters compatible with placeholders "{}".
|
||||||
|
*
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public interface Logger {
|
||||||
|
/**
|
||||||
|
* Log a message at the INFO level according to the specified format
|
||||||
|
* and arguments.
|
||||||
|
* @param format the format string
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
*/
|
||||||
|
void info(String format, Object... arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exception (throwable) at the INFO level with an
|
||||||
|
* accompanying message.
|
||||||
|
*
|
||||||
|
* @param msg the message accompanying the exception
|
||||||
|
* @param e the exception (throwable) to log
|
||||||
|
*/
|
||||||
|
void info(String msg, Throwable e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message at the WARN level according to the specified format
|
||||||
|
* and arguments.
|
||||||
|
* @param format the format string
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
*/
|
||||||
|
void warn(String format, Object... arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exception (throwable) at the WARN level with an
|
||||||
|
* accompanying message.
|
||||||
|
*
|
||||||
|
* @param msg the message accompanying the exception
|
||||||
|
* @param e the exception (throwable) to log
|
||||||
|
*/
|
||||||
|
void warn(String msg, Throwable e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message at the TRACE level according to the specified format
|
||||||
|
* and arguments.
|
||||||
|
* @param format the format string
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
*/
|
||||||
|
void trace(String format, Object... arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exception (throwable) at the TRACE level with an
|
||||||
|
* accompanying message.
|
||||||
|
*
|
||||||
|
* @param msg the message accompanying the exception
|
||||||
|
* @param e the exception (throwable) to log
|
||||||
|
*/
|
||||||
|
void trace(String msg, Throwable e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message at the DEBUG level according to the specified format
|
||||||
|
* and arguments.
|
||||||
|
* @param format the format string
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
*/
|
||||||
|
void debug(String format, Object... arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exception (throwable) at the DEBUG level with an
|
||||||
|
* accompanying message.
|
||||||
|
*
|
||||||
|
* @param msg the message accompanying the exception
|
||||||
|
* @param e the exception (throwable) to log
|
||||||
|
*/
|
||||||
|
void debug(String msg, Throwable e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message at the ERROR level according to the specified format
|
||||||
|
* and arguments.
|
||||||
|
* @param format the format string
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
*/
|
||||||
|
void error(String format, Object... arguments);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an exception (throwable) at the ERROR level with an
|
||||||
|
* accompanying message.
|
||||||
|
*
|
||||||
|
* @param msg the message accompanying the exception
|
||||||
|
* @param e the exception (throwable) to log
|
||||||
|
*/
|
||||||
|
void error(String msg, Throwable e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,427 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright notice
|
||||||
|
* This code copy from SLF4J which licensed under the MIT License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright notice
|
||||||
|
* This code copy from SLF4J which licensed under the MIT License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
|
||||||
|
// contributors: lizongbo: proposed special treatment of array parameter values
|
||||||
|
// Joern Huxhorn: pointed out double[] omission, suggested deep array copy
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats messages according to very simple substitution rules. Substitutions
|
||||||
|
* can be made 1, 2 or more arguments.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("Hi {}.", "there")
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "Hi there.".
|
||||||
|
* <p>
|
||||||
|
* The {} pair is called the <em>formatting anchor</em>. It serves to designate
|
||||||
|
* the location where arguments need to be substituted within the message
|
||||||
|
* pattern.
|
||||||
|
* <p>
|
||||||
|
* In case your message contains the '{' or the '}' character, you do not have
|
||||||
|
* to do anything special unless the '}' character immediately follows '{'. For
|
||||||
|
* example,
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("Set {1,2,3} is not equal to {}.", "1,2");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "Set {1,2,3} is not equal to 1,2.".
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* If for whatever reason you need to place the string "{}" in the message
|
||||||
|
* without its <em>formatting anchor</em> meaning, then you need to escape the
|
||||||
|
* '{' character with '\', that is the backslash character. Only the '{'
|
||||||
|
* character should be escaped. There is no need to escape the '}' character.
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("Set \\{} is not equal to {}.", "1,2");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "Set {} is not equal to 1,2.".
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The escaping behavior just described can be overridden by escaping the escape
|
||||||
|
* character '\'. Calling
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "File name is C:\file.zip".
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The formatting conventions are different than those of {@link MessageFormat}
|
||||||
|
* which ships with the Java platform. This is justified by the fact that
|
||||||
|
* SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
|
||||||
|
* This local performance difference is both measurable and significant in the
|
||||||
|
* larger context of the complete logging processing chain.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* See also {@link #format(String, Object)},
|
||||||
|
* {@link #format(String, Object, Object)} and
|
||||||
|
* {@link #arrayFormat(String, Object[])} methods for more details.
|
||||||
|
*
|
||||||
|
* @author Ceki Gülcü
|
||||||
|
* @author Joern Huxhorn
|
||||||
|
*/
|
||||||
|
final public class MessageFormatter {
|
||||||
|
static final char DELIM_START = '{';
|
||||||
|
static final char DELIM_STOP = '}';
|
||||||
|
static final String DELIM_STR = "{}";
|
||||||
|
private static final char ESCAPE_CHAR = '\\';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs single argument substitution for the 'messagePattern' passed as
|
||||||
|
* parameter.
|
||||||
|
* <p>
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("Hi {}.", "there");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "Hi there.".
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param messagePattern
|
||||||
|
* The message pattern which will be parsed and formatted
|
||||||
|
* @param arg
|
||||||
|
* The argument to be substituted in place of the formatting anchor
|
||||||
|
* @return The formatted message
|
||||||
|
*/
|
||||||
|
final public static FormattingTuple format(String messagePattern, Object arg) {
|
||||||
|
return arrayFormat(messagePattern, new Object[] { arg });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Performs a two argument substitution for the 'messagePattern' passed as
|
||||||
|
* parameter.
|
||||||
|
* <p>
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* MessageFormatter.format("Hi {}. My name is {}.", "Alice", "Bob");
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* will return the string "Hi Alice. My name is Bob.".
|
||||||
|
*
|
||||||
|
* @param messagePattern
|
||||||
|
* The message pattern which will be parsed and formatted
|
||||||
|
* @param arg1
|
||||||
|
* The argument to be substituted in place of the first formatting
|
||||||
|
* anchor
|
||||||
|
* @param arg2
|
||||||
|
* The argument to be substituted in place of the second formatting
|
||||||
|
* anchor
|
||||||
|
* @return The formatted message
|
||||||
|
*/
|
||||||
|
final public static FormattingTuple format(final String messagePattern, Object arg1, Object arg2) {
|
||||||
|
return arrayFormat(messagePattern, new Object[] { arg1, arg2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static final Throwable getThrowableCandidate(Object[] argArray) {
|
||||||
|
if (argArray == null || argArray.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object lastEntry = argArray[argArray.length - 1];
|
||||||
|
if (lastEntry instanceof Throwable) {
|
||||||
|
return (Throwable) lastEntry;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
|
||||||
|
Throwable throwableCandidate = getThrowableCandidate(argArray);
|
||||||
|
Object[] args = argArray;
|
||||||
|
if (throwableCandidate != null) {
|
||||||
|
args = trimmedCopy(argArray);
|
||||||
|
}
|
||||||
|
return arrayFormat(messagePattern, args, throwableCandidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object[] trimmedCopy(Object[] argArray) {
|
||||||
|
if (argArray == null || argArray.length == 0) {
|
||||||
|
throw new IllegalStateException("non-sensical empty or null argument array");
|
||||||
|
}
|
||||||
|
final int trimemdLen = argArray.length - 1;
|
||||||
|
Object[] trimmed = new Object[trimemdLen];
|
||||||
|
System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
|
||||||
|
return trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) {
|
||||||
|
|
||||||
|
if (messagePattern == null) {
|
||||||
|
return new FormattingTuple(null, argArray, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argArray == null) {
|
||||||
|
return new FormattingTuple(messagePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j;
|
||||||
|
// use string builder for better multicore performance
|
||||||
|
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
|
||||||
|
|
||||||
|
int L;
|
||||||
|
for (L = 0; L < argArray.length; L++) {
|
||||||
|
|
||||||
|
j = messagePattern.indexOf(DELIM_STR, i);
|
||||||
|
|
||||||
|
if (j == -1) {
|
||||||
|
// no more variables
|
||||||
|
if (i == 0) { // this is a simple string
|
||||||
|
return new FormattingTuple(messagePattern, argArray, throwable);
|
||||||
|
} else { // add the tail string which contains no variables and return
|
||||||
|
// the result.
|
||||||
|
sbuf.append(messagePattern, i, messagePattern.length());
|
||||||
|
return new FormattingTuple(sbuf.toString(), argArray, throwable);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isEscapedDelimeter(messagePattern, j)) {
|
||||||
|
if (!isDoubleEscaped(messagePattern, j)) {
|
||||||
|
L--; // DELIM_START was escaped, thus should not be incremented
|
||||||
|
sbuf.append(messagePattern, i, j - 1);
|
||||||
|
sbuf.append(DELIM_START);
|
||||||
|
i = j + 1;
|
||||||
|
} else {
|
||||||
|
// The escape character preceding the delimiter start is
|
||||||
|
// itself escaped: "abc x:\\{}"
|
||||||
|
// we have to consume one backward slash
|
||||||
|
sbuf.append(messagePattern, i, j - 1);
|
||||||
|
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
|
||||||
|
i = j + 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// normal case
|
||||||
|
sbuf.append(messagePattern, i, j);
|
||||||
|
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
|
||||||
|
i = j + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// append the characters following the last {} pair.
|
||||||
|
sbuf.append(messagePattern, i, messagePattern.length());
|
||||||
|
return new FormattingTuple(sbuf.toString(), argArray, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
|
||||||
|
|
||||||
|
if (delimeterStartIndex == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1);
|
||||||
|
if (potentialEscape == ESCAPE_CHAR) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) {
|
||||||
|
if (delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// special treatment of array values was suggested by 'lizongbo'
|
||||||
|
private static void deeplyAppendParameter(StringBuilder sbuf, Object o, Map<Object[], Object> seenMap) {
|
||||||
|
if (o == null) {
|
||||||
|
sbuf.append("null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!o.getClass().isArray()) {
|
||||||
|
safeObjectAppend(sbuf, o);
|
||||||
|
} else {
|
||||||
|
// check for primitive array types because they
|
||||||
|
// unfortunately cannot be cast to Object[]
|
||||||
|
if (o instanceof boolean[]) {
|
||||||
|
booleanArrayAppend(sbuf, (boolean[]) o);
|
||||||
|
} else if (o instanceof byte[]) {
|
||||||
|
byteArrayAppend(sbuf, (byte[]) o);
|
||||||
|
} else if (o instanceof char[]) {
|
||||||
|
charArrayAppend(sbuf, (char[]) o);
|
||||||
|
} else if (o instanceof short[]) {
|
||||||
|
shortArrayAppend(sbuf, (short[]) o);
|
||||||
|
} else if (o instanceof int[]) {
|
||||||
|
intArrayAppend(sbuf, (int[]) o);
|
||||||
|
} else if (o instanceof long[]) {
|
||||||
|
longArrayAppend(sbuf, (long[]) o);
|
||||||
|
} else if (o instanceof float[]) {
|
||||||
|
floatArrayAppend(sbuf, (float[]) o);
|
||||||
|
} else if (o instanceof double[]) {
|
||||||
|
doubleArrayAppend(sbuf, (double[]) o);
|
||||||
|
} else {
|
||||||
|
objectArrayAppend(sbuf, (Object[]) o, seenMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void safeObjectAppend(StringBuilder sbuf, Object o) {
|
||||||
|
try {
|
||||||
|
String oAsString = o.toString();
|
||||||
|
sbuf.append(oAsString);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
sbuf.append("[FAILED toString()]");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void objectArrayAppend(StringBuilder sbuf, Object[] a, Map<Object[], Object> seenMap) {
|
||||||
|
sbuf.append('[');
|
||||||
|
if (!seenMap.containsKey(a)) {
|
||||||
|
seenMap.put(a, null);
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
deeplyAppendParameter(sbuf, a[i], seenMap);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allow repeats in siblings
|
||||||
|
seenMap.remove(a);
|
||||||
|
} else {
|
||||||
|
sbuf.append("...");
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void byteArrayAppend(StringBuilder sbuf, byte[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void charArrayAppend(StringBuilder sbuf, char[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void shortArrayAppend(StringBuilder sbuf, short[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void intArrayAppend(StringBuilder sbuf, int[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void longArrayAppend(StringBuilder sbuf, long[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void floatArrayAppend(StringBuilder sbuf, float[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void doubleArrayAppend(StringBuilder sbuf, double[] a) {
|
||||||
|
sbuf.append('[');
|
||||||
|
final int len = a.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sbuf.append(a[i]);
|
||||||
|
if (i != len - 1) {
|
||||||
|
sbuf.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sbuf.append(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -15,9 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package com.alibaba.csp.sentinel.log;
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
import java.util.logging.Handler;
|
import java.util.Iterator;
|
||||||
import java.util.logging.Level;
|
import java.util.ServiceLoader;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* The basic logger for vital events.
|
* The basic logger for vital events.
|
||||||
|
|
@ -25,27 +24,71 @@ import java.util.logging.Logger;
|
||||||
* @author youji.zj
|
* @author youji.zj
|
||||||
*/
|
*/
|
||||||
public class RecordLog extends LogBase {
|
public class RecordLog extends LogBase {
|
||||||
private static final Logger heliumRecordLog = Logger.getLogger("cspSentinelRecordLog");
|
private static com.alibaba.csp.sentinel.log.Logger log = null;
|
||||||
private static final String FILE_NAME = "sentinel-record.log";
|
|
||||||
private static Handler logHandler = null;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
logHandler = makeLogger(FILE_NAME, heliumRecordLog);
|
ServiceLoader<Logger> load = ServiceLoader.load(Logger.class);
|
||||||
|
Logger logger = null;
|
||||||
|
Iterator<Logger> iterator = load.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Logger next = iterator.next();
|
||||||
|
LogTarget annotation = next.getClass().getAnnotation(LogTarget.class);
|
||||||
|
if (annotation == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String value = annotation.value().name();
|
||||||
|
if (value.equals(LogType.RECORD_LOG.name())) {
|
||||||
|
logger = next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use user implementations.
|
||||||
|
if (logger != null) {
|
||||||
|
log = logger;
|
||||||
|
} else {
|
||||||
|
// Use default implementations.
|
||||||
|
log = new RecordLogLogging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String detail, Object... params) {
|
public static void info(String format, Object... arguments) {
|
||||||
log(heliumRecordLog, logHandler, Level.INFO, detail, params);
|
log.info(format, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void info(String detail, Throwable e) {
|
public static void info(String msg, Throwable e) {
|
||||||
log(heliumRecordLog, logHandler, Level.INFO, detail, e);
|
log.info(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warn(String detail, Object... params) {
|
public static void warn(String format, Object... arguments) {
|
||||||
log(heliumRecordLog, logHandler, Level.WARNING, detail, params);
|
log.warn(format, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void warn(String detail, Throwable e) {
|
public static void warn(String msg, Throwable e) {
|
||||||
log(heliumRecordLog, logHandler, Level.WARNING, detail, e);
|
log.warn(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void trace(String format, Object... arguments) {
|
||||||
|
log.trace(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void trace(String msg, Throwable e) {
|
||||||
|
log.trace(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String format, Object... arguments) {
|
||||||
|
log.debug(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String msg, Throwable e) {
|
||||||
|
log.debug(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String format, Object... arguments) {
|
||||||
|
log.error(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String msg, Throwable e) {
|
||||||
|
log.error(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.log;
|
||||||
|
|
||||||
|
import java.util.logging.Handler;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default logger implementation.
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public class RecordLogLogging extends LogBase implements com.alibaba.csp.sentinel.log.Logger {
|
||||||
|
private final Logger heliumRecordLog = Logger.getLogger("cspSentinelRecordLog");
|
||||||
|
private final String FILE_NAME = "sentinel-record.log";
|
||||||
|
private final Handler logHandler = makeLogger(FILE_NAME, heliumRecordLog);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.INFO, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.INFO, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.WARNING, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.WARNING, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.TRACE, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.TRACE, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.DEBUG, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.DEBUG, msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object... arguments) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.ERROR, format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg, Throwable e) {
|
||||||
|
log(heliumRecordLog, logHandler, Level.ERROR, msg, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,4 +107,14 @@ public class RecordLogTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Because log only writes into the file,
|
||||||
|
// can't read the log(file conflict), so no assertion in this unit test.
|
||||||
|
@Test
|
||||||
|
public void testMessageFormatter() {
|
||||||
|
RecordLog.info("1 2 {} 4 {} 6", "3", "5");
|
||||||
|
RecordLog.info("1 2 {} 4 {} 6", "3");
|
||||||
|
RecordLog.info("1 2 {} 4 {} 6");
|
||||||
|
|
||||||
|
RecordLog.info("1 2 \\{} 4 {} 6", "5");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
<module>sentinel-demo-zuul-gateway</module>
|
<module>sentinel-demo-zuul-gateway</module>
|
||||||
<module>sentinel-demo-etcd-datasource</module>
|
<module>sentinel-demo-etcd-datasource</module>
|
||||||
<module>sentinel-demo-spring-webmvc</module>
|
<module>sentinel-demo-spring-webmvc</module>
|
||||||
|
<module>sentinel-demo-log-logback</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>sentinel-demo</artifactId>
|
||||||
|
<groupId>com.alibaba.csp</groupId>
|
||||||
|
<version>1.7.2-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>sentinel-demo-log-logback</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.2.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.stefanbirkner</groupId>
|
||||||
|
<artifactId>system-rules</artifactId>
|
||||||
|
<version>RELEASE</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.demo.log.logback;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.log.LogTarget;
|
||||||
|
import com.alibaba.csp.sentinel.log.LogType;
|
||||||
|
import com.alibaba.csp.sentinel.log.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a demo shows how to create a customized logger implementation.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>1. Create a class which implements the {@link Logger} SPI interface</li>
|
||||||
|
* <li>2. Use a {@link LogTarget} to specify the log type</li>
|
||||||
|
* <li>3. Implement your own method </li>
|
||||||
|
* <li>4. Add your logger in {@code com.alibaba.csp.sentinel.log.Logger} file which is stored in
|
||||||
|
* {@code resources/META-INF/services/} directory </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
@LogTarget(value = LogType.COMMAND_CENTER_LOG)
|
||||||
|
public class CommandCenterLogLoggerImpl implements Logger {
|
||||||
|
private final org.slf4j.Logger logger = LoggerFactory.getLogger("commandCenterLogLogger");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object... arguments) {
|
||||||
|
logger.info(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg, Throwable e) {
|
||||||
|
logger.info(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object... arguments) {
|
||||||
|
logger.warn(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg, Throwable e) {
|
||||||
|
logger.warn(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object... arguments) {
|
||||||
|
logger.trace(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg, Throwable e) {
|
||||||
|
logger.trace(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object... arguments) {
|
||||||
|
logger.debug(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg, Throwable e) {
|
||||||
|
logger.debug(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object... arguments) {
|
||||||
|
logger.error(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg, Throwable e) {
|
||||||
|
logger.error(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.demo.log.logback;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.log.LogTarget;
|
||||||
|
import com.alibaba.csp.sentinel.log.LogType;
|
||||||
|
import com.alibaba.csp.sentinel.log.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a demo shows how to create a customized logger implementation.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>1. Create a class which implements the {@link Logger} SPI interface</li>
|
||||||
|
* <li>2. Use a {@link LogTarget} to specify the log type</li>
|
||||||
|
* <li>3. Implement your own method </li>
|
||||||
|
* <li>4. Add your logger in {@code com.alibaba.csp.sentinel.log.Logger} file which is stored in
|
||||||
|
* {@code resources/META-INF/services/} directory </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
@LogTarget(value = LogType.RECORD_LOG)
|
||||||
|
public class RecordLogLoggerImpl implements Logger {
|
||||||
|
private final org.slf4j.Logger logger = LoggerFactory.getLogger("recordLogLogger");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String format, Object... arguments) {
|
||||||
|
logger.info(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String msg, Throwable e) {
|
||||||
|
logger.info(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String format, Object... arguments) {
|
||||||
|
logger.warn(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warn(String msg, Throwable e) {
|
||||||
|
logger.warn(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String format, Object... arguments) {
|
||||||
|
logger.trace(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void trace(String msg, Throwable e) {
|
||||||
|
logger.trace(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String format, Object... arguments) {
|
||||||
|
logger.debug(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String msg, Throwable e) {
|
||||||
|
logger.debug(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String format, Object... arguments) {
|
||||||
|
logger.error(format, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String msg, Throwable e) {
|
||||||
|
logger.error(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
com.alibaba.csp.sentinel.demo.log.logback.RecordLogLoggerImpl
|
||||||
|
com.alibaba.csp.sentinel.demo.log.logback.CommandCenterLogLoggerImpl
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<configuration scan="false" scanPeriod="60000" debug="false">
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<pattern>%-5level %logger - %msg%n</pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>sentinel-record.log</file>
|
||||||
|
<append>true</append>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%-5level %logger - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="FILE2" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>sentinel-command-center.log</file>
|
||||||
|
<append>true</append>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%-5level %logger - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="recordLogLogger" level="trace">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="commandCenterLogLogger" level="trace">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
<appender-ref ref="FILE2" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<!--<root level="info">-->
|
||||||
|
<!--<appender-ref ref="STDOUT" />-->
|
||||||
|
<!--<appender-ref ref="FILE" />-->
|
||||||
|
<!--</root>-->
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.demo.log.logback;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.log.CommandCenterLog;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.contrib.java.lang.system.SystemOutRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public class CommandCenterLogTest {
|
||||||
|
@Rule
|
||||||
|
public SystemOutRule log = new SystemOutRule().enableLog();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLog() {
|
||||||
|
CommandCenterLog.info("init");
|
||||||
|
log.clearLog();
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
// info test
|
||||||
|
while (count++ < 1000) {
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.info("Count {}", count);
|
||||||
|
String str = String.format("INFO commandCenterLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// warn test
|
||||||
|
while (count++ < 2000) {
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.warn("Count {}", count);
|
||||||
|
String str = String.format("WARN commandCenterLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace test
|
||||||
|
while (count++ < 3000) {
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.trace("Count {}", count);
|
||||||
|
String str = String.format("TRACE commandCenterLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug test
|
||||||
|
while (count++ < 4000) {
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.debug("Count {}", count);
|
||||||
|
String str = String.format("DEBUG commandCenterLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// test error
|
||||||
|
while (count++ < 5000) {
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.error("Count {}", count);
|
||||||
|
String str = String.format("ERROR commandCenterLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogException() {
|
||||||
|
CommandCenterLog.info("init");
|
||||||
|
log.clearLog();
|
||||||
|
Exception e = new Exception("ex");
|
||||||
|
|
||||||
|
// info test
|
||||||
|
CommandCenterLog.info("Error", e);
|
||||||
|
// split the log for test
|
||||||
|
String[] logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("INFO commandCenterLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// warn test
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.warn("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("WARN commandCenterLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// trace test
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.trace("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("TRACE commandCenterLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// debug test
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.debug("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("DEBUG commandCenterLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// error test
|
||||||
|
log.clearLog();
|
||||||
|
CommandCenterLog.error("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("ERROR commandCenterLogLogger - Error", logSplit[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.csp.sentinel.demo.log.logback;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.contrib.java.lang.system.SystemOutRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xue8
|
||||||
|
*/
|
||||||
|
public class RecordLogTest {
|
||||||
|
@Rule
|
||||||
|
public SystemOutRule log = new SystemOutRule().enableLog();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLog() {
|
||||||
|
RecordLog.info("init");
|
||||||
|
log.clearLog();
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
// info test
|
||||||
|
while (count++ < 1000) {
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.info("Count {}", count);
|
||||||
|
String str = String.format("INFO recordLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// warn test
|
||||||
|
while (count++ < 2000) {
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.warn("Count {}", count);
|
||||||
|
String str = String.format("WARN recordLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace test
|
||||||
|
while (count++ < 3000) {
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.trace("Count {}", count);
|
||||||
|
String str = String.format("TRACE recordLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug test
|
||||||
|
while (count++ < 4000) {
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.debug("Count {}", count);
|
||||||
|
String str = String.format("DEBUG recordLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
|
||||||
|
// test error
|
||||||
|
while (count++ < 5000) {
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.error("Count {}", count);
|
||||||
|
String str = String.format("ERROR recordLogLogger - Count %d" + System.lineSeparator(), count);
|
||||||
|
Assert.assertEquals(str, log.getLog());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogException() {
|
||||||
|
RecordLog.info("init");
|
||||||
|
log.clearLog();
|
||||||
|
Exception e = new Exception("ex");
|
||||||
|
|
||||||
|
// info test
|
||||||
|
RecordLog.info("Error", e);
|
||||||
|
// split the log for test
|
||||||
|
String[] logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("INFO recordLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// warn test
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.warn("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("WARN recordLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// trace test
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.trace("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("TRACE recordLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// debug test
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.debug("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("DEBUG recordLogLogger - Error", logSplit[0]);
|
||||||
|
|
||||||
|
// error test
|
||||||
|
log.clearLog();
|
||||||
|
RecordLog.error("Error", e);
|
||||||
|
logSplit = log.getLog().split(System.lineSeparator());
|
||||||
|
Assert.assertEquals("ERROR recordLogLogger - Error", logSplit[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue