Config whether pid is needed in the log file name (#194)
- Change log file name; - Add configurability to log file name and metric file name.
This commit is contained in:
parent
0855809149
commit
85c844eb9c
|
|
@ -25,7 +25,7 @@ import java.util.logging.Logger;
|
|||
public class CommandCenterLog extends LogBase {
|
||||
|
||||
private static final Logger heliumRecordLog = Logger.getLogger("cspCommandCenterLog");
|
||||
private static final String FILE_NAME = "commandCenter.log";
|
||||
private static final String FILE_NAME = "command-center.log";
|
||||
private static Handler logHandler = null;
|
||||
|
||||
static {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ import java.util.logging.Logger;
|
|||
import com.alibaba.csp.sentinel.util.PidUtil;
|
||||
|
||||
/**
|
||||
* Default log base dir is ${user.home}, we can use {@link #LOG_DIR} System property to override it.
|
||||
* Default log base dir is ${user.home}/logs/csp/, we can use {@link #LOG_DIR} System property to override it.
|
||||
* Default log file name dose not contain pid, but if multi instances of the same app are running in the same
|
||||
* machine, we may want to distinguish the log file by pid number, in this case, {@link #LOG_NAME_USE_PID}
|
||||
* System property could be configured as "true" to turn on this switch.
|
||||
*
|
||||
* @author leyou
|
||||
*/
|
||||
|
|
@ -33,9 +36,21 @@ public class LogBase {
|
|||
private static final String DIR_NAME = "logs" + File.separator + "csp";
|
||||
private static final String USER_HOME = "user.home";
|
||||
public static final String LOG_DIR = "csp.sentinel.log.dir";
|
||||
public static final String LOG_NAME_USE_PID = "csp.sentinel.log.use.pid";
|
||||
private static boolean logNameUsePid = false;
|
||||
|
||||
private static String logBaseDir;
|
||||
|
||||
static {
|
||||
try {
|
||||
init();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
// first use -D, then use user home.
|
||||
String logDir = System.getProperty(LOG_DIR);
|
||||
|
||||
|
|
@ -53,6 +68,19 @@ public class LogBase {
|
|||
// logBaseDir must end with File.separator
|
||||
logBaseDir = logDir;
|
||||
System.out.println("INFO: log base dir is: " + logBaseDir);
|
||||
|
||||
String usePid = System.getProperty(LOG_NAME_USE_PID, "");
|
||||
logNameUsePid = "true".equalsIgnoreCase(usePid);
|
||||
System.out.println("INFO: log name use pid is: " + logNameUsePid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether log file name should contain pid. This switch is configured by {@link #LOG_NAME_USE_PID} System property.
|
||||
*
|
||||
* @return if log file name should contain pid, return true, otherwise return false.
|
||||
*/
|
||||
public static boolean isLogNameUsePid() {
|
||||
return logNameUsePid;
|
||||
}
|
||||
|
||||
private static String addSeparator(String logDir) {
|
||||
|
|
@ -61,7 +89,7 @@ public class LogBase {
|
|||
}
|
||||
return logDir;
|
||||
}
|
||||
|
||||
|
||||
protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) {
|
||||
if (detail == null) {
|
||||
return;
|
||||
|
|
@ -73,7 +101,7 @@ public class LogBase {
|
|||
logger.log(level, detail, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static void log(Logger logger, Handler handler, Level level, String detail, Throwable throwable) {
|
||||
if (detail == null) {
|
||||
return;
|
||||
|
|
@ -93,7 +121,10 @@ public class LogBase {
|
|||
|
||||
protected static Handler makeLogger(String logName, Logger heliumRecordLog) {
|
||||
CspFormatter formatter = new CspFormatter();
|
||||
String fileName = LogBase.getLogBaseDir() + logName + ".pid" + PidUtil.getPid();
|
||||
String fileName = LogBase.getLogBaseDir() + logName;
|
||||
if (isLogNameUsePid()) {
|
||||
fileName += ".pid" + PidUtil.getPid();
|
||||
}
|
||||
Handler handler = null;
|
||||
try {
|
||||
handler = new DateFileLogHandler(fileName + ".%d", 1024 * 1024 * 200, 4, true);
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ import java.util.logging.Logger;
|
|||
* @author youji.zj
|
||||
*/
|
||||
public class RecordLog extends LogBase {
|
||||
private static final Logger heliumRecordLog = Logger.getLogger("cspRecordLog");
|
||||
private static final String FILE_NAME = "record.log";
|
||||
private static final Logger heliumRecordLog = Logger.getLogger("cspSentinelRecordLog");
|
||||
private static final String FILE_NAME = "sentinel-record.log";
|
||||
private static Handler logHandler = null;
|
||||
|
||||
static {
|
||||
logHandler = makeLogger(FILE_NAME, heliumRecordLog);
|
||||
}
|
||||
|
||||
|
||||
public static void info(String detail, Object... params) {
|
||||
log(heliumRecordLog, logHandler, Level.INFO, detail, params);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.Comparator;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.LogBase;
|
||||
import com.alibaba.csp.sentinel.util.PidUtil;
|
||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
|
|
@ -36,7 +37,7 @@ import com.alibaba.csp.sentinel.log.RecordLog;
|
|||
* <ol>
|
||||
* <li>metric with the same second should write to the same file;</li>
|
||||
* <li>single file size must be controlled;</li>
|
||||
* <li>file name is like: {@code ${AppName}_pid-metrics.log.yyyy-MM-dd.[number]}</li>
|
||||
* <li>file name is like: {@code ${appName}-metrics.log.pid${pid}.yyyy-MM-dd.[number]}</li>
|
||||
* <li>metric of different day should in different file;</li>
|
||||
* <li>every metric file is accompanied with an index file, which file name is {@code ${metricFileName}.idx}</li>
|
||||
* </ol>
|
||||
|
|
@ -47,16 +48,21 @@ public class MetricWriter {
|
|||
|
||||
private static final String CHARSET = SentinelConfig.charset();
|
||||
public static final String METRIC_BASE_DIR = RecordLog.getLogBaseDir();
|
||||
public static final String METRIC_FILE_SUFFIX = "-metrics.log";
|
||||
/**
|
||||
* Note: {@link MetricFileNameComparator}'s implementation relays on the metric file name,
|
||||
* we should be careful when changing the metric file name.
|
||||
*
|
||||
* @see #formMetricFileName(String, int)
|
||||
*/
|
||||
public static final String METRIC_FILE = "metrics.log";
|
||||
public static final String METRIC_FILE_INDEX_SUFFIX = ".idx";
|
||||
public static final Comparator<String> METRIC_FILENAME_CMP = new MetricFileNameComparator();
|
||||
public static final Comparator<String> METRIC_FILE_NAME_CMP = new MetricFileNameComparator();
|
||||
|
||||
private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
/**
|
||||
* 排除时差干扰
|
||||
*/
|
||||
private long timeSecondBase;
|
||||
private final StringBuilder sb = new StringBuilder(32);
|
||||
private String baseDir;
|
||||
private String baseFileName;
|
||||
/**
|
||||
|
|
@ -86,7 +92,9 @@ public class MetricWriter {
|
|||
if (singleFileSize <= 0 || totalFileCount <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
RecordLog.info("[MetricWriter] Creating new MetricWriter, singleFileSize=" + singleFileSize + ", totalFileCount=" + totalFileCount);
|
||||
RecordLog.info(
|
||||
"[MetricWriter] Creating new MetricWriter, singleFileSize=" + singleFileSize + ", totalFileCount="
|
||||
+ totalFileCount);
|
||||
this.baseDir = METRIC_BASE_DIR;
|
||||
File dir = new File(baseDir);
|
||||
if (!dir.exists()) {
|
||||
|
|
@ -193,7 +201,7 @@ public class MetricWriter {
|
|||
list.add(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
Collections.sort(list, METRIC_FILENAME_CMP);
|
||||
Collections.sort(list, METRIC_FILE_NAME_CMP);
|
||||
if (list.isEmpty()) {
|
||||
return baseDir + baseFileName + "." + dateStr;
|
||||
}
|
||||
|
|
@ -209,30 +217,38 @@ public class MetricWriter {
|
|||
/**
|
||||
* A comparator for metric file name. Metric file name is like: <br/>
|
||||
* <pre>
|
||||
* aliswitch-8728-metrics.log.2018-03-06
|
||||
* aliswitch-8728-metrics.log.2018-03-07
|
||||
* aliswitch-8728-metrics.log.2018-03-07.10
|
||||
* aliswitch-8728-metrics.log.2018-03-06.100
|
||||
* metrics.log.2018-03-06
|
||||
* metrics.log.2018-03-07
|
||||
* metrics.log.2018-03-07.10
|
||||
* metrics.log.2018-03-06.100
|
||||
* </pre>
|
||||
* <p>
|
||||
* File name with the early date is smaller, if date is same, the one with the small file number is smaller.
|
||||
* Note that if the name is an absolute path, only the fileName({@link File#getName()}) part will be considered.
|
||||
* So the above file names should be sorted as: <br/>
|
||||
* <pre>
|
||||
* aliswitch-8728-metrics.log.2018-03-06
|
||||
* aliswitch-8728-metrics.log.2018-03-06.100
|
||||
* aliswitch-8728-metrics.log.2018-03-07
|
||||
* aliswitch-8728-metrics.log.2018-03-07.10
|
||||
* metrics.log.2018-03-06
|
||||
* metrics.log.2018-03-06.100
|
||||
* metrics.log.2018-03-07
|
||||
* metrics.log.2018-03-07.10
|
||||
*
|
||||
* </pre>
|
||||
* </p>
|
||||
*/
|
||||
private static final class MetricFileNameComparator implements Comparator<String> {
|
||||
private final String pid = "pid";
|
||||
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
String name1 = new File(o1).getName();
|
||||
String name2 = new File(o2).getName();
|
||||
String dateStr1 = name1.split("\\.")[2];
|
||||
String dateStr2 = name2.split("\\.")[2];
|
||||
// in case of file name contains pid, skip it
|
||||
if (dateStr1.startsWith(pid)) {
|
||||
dateStr1 = name1.split("\\.")[3];
|
||||
dateStr2 = name2.split("\\.")[3];
|
||||
}
|
||||
|
||||
// compare date first
|
||||
int t = dateStr1.compareTo(dateStr2);
|
||||
|
|
@ -273,7 +289,7 @@ public class MetricWriter {
|
|||
list.add(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
Collections.sort(list, MetricWriter.METRIC_FILENAME_CMP);
|
||||
Collections.sort(list, MetricWriter.METRIC_FILE_NAME_CMP);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
@ -323,9 +339,12 @@ public class MetricWriter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Form metric file name use the specific appName and pid. Not that only
|
||||
* Form metric file name use the specific appName and pid. Note that only
|
||||
* form the file name, not include path.
|
||||
*
|
||||
* Note: {@link MetricFileNameComparator}'s implementation relays on the metric file name,
|
||||
* we should be careful when changing the metric file name.
|
||||
*
|
||||
* @param appName
|
||||
* @param pid
|
||||
* @return metric file name.
|
||||
|
|
@ -334,7 +353,17 @@ public class MetricWriter {
|
|||
if (appName == null) {
|
||||
appName = "";
|
||||
}
|
||||
return appName + "-" + pid + METRIC_FILE_SUFFIX;
|
||||
// dot is special char that should be replaced.
|
||||
final String dot = ".";
|
||||
final String separator = "-";
|
||||
if (appName.contains(dot)) {
|
||||
appName = appName.replace(dot, separator);
|
||||
}
|
||||
String name = appName + separator + METRIC_FILE;
|
||||
if (LogBase.isLogNameUsePid()) {
|
||||
name += ".pid" + pid;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import java.io.File;
|
|||
|
||||
import com.alibaba.csp.sentinel.log.LogBase;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.util.PidUtil;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
@ -61,4 +62,30 @@ public class RecordLogTest {
|
|||
assertTrue(RecordLog.getLogBaseDir().startsWith(System.getProperty("user.home")));
|
||||
}
|
||||
|
||||
public void testLogNameNotUsePid() {
|
||||
String userHome = System.getProperty("user.home");
|
||||
String newLogBase = userHome + File.separator + "tmpLogDir" + System.currentTimeMillis();
|
||||
System.setProperty(LogBase.LOG_DIR, newLogBase);
|
||||
RecordLog.info("testLogNameNotUsePid");
|
||||
File[] files = new File(newLogBase).listFiles();
|
||||
assertTrue(files != null && files.length > 0);
|
||||
for (File f : files) {
|
||||
assertTrue(!f.getName().contains("pid" + PidUtil.getPid()));
|
||||
}
|
||||
}
|
||||
|
||||
public void testLogNameUsePid() {
|
||||
String userHome = System.getProperty("user.home");
|
||||
String newLogBase = userHome + File.separator + "tmpLogDir" + System.currentTimeMillis();
|
||||
System.setProperty(LogBase.LOG_DIR, newLogBase);
|
||||
System.setProperty(LogBase.LOG_NAME_USE_PID, "true");
|
||||
|
||||
RecordLog.info("testLogNameUsePid");
|
||||
File[] files = new File(newLogBase).listFiles();
|
||||
assertTrue(files != null && files.length > 0);
|
||||
for (File f : files) {
|
||||
assertTrue(f.getName().contains("pid" + PidUtil.getPid()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.alibaba.csp.sentinel.node.metric;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class MetricWriterTest {
|
||||
@Test
|
||||
public void testFileNameCmp() {
|
||||
String[] arr = new String[] {
|
||||
"metrics.log.2018-03-06",
|
||||
"metrics.log.2018-03-07",
|
||||
"metrics.log.2018-03-07.51",
|
||||
"metrics.log.2018-03-07.10",
|
||||
"metrics.log.2018-03-06.100"
|
||||
};
|
||||
String[] key = new String[] {
|
||||
"metrics.log.2018-03-06",
|
||||
"metrics.log.2018-03-06.100",
|
||||
"metrics.log.2018-03-07",
|
||||
"metrics.log.2018-03-07.10",
|
||||
"metrics.log.2018-03-07.51"
|
||||
};
|
||||
ArrayList<String> list = new ArrayList<String>(Arrays.asList(arr));
|
||||
Collections.sort(list, MetricWriter.METRIC_FILE_NAME_CMP);
|
||||
assertEquals(Arrays.asList(key), list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileNamePidCmp() {
|
||||
String[] arr = new String[] {
|
||||
"metrics.log.pid1234.2018-03-06",
|
||||
"metrics.log.pid1234.2018-03-07",
|
||||
"metrics.log.pid1234.2018-03-07.51",
|
||||
"metrics.log.pid1234.2018-03-07.10",
|
||||
"metrics.log.pid1234.2018-03-06.100"
|
||||
};
|
||||
String[] key = new String[] {
|
||||
"metrics.log.pid1234.2018-03-06",
|
||||
"metrics.log.pid1234.2018-03-06.100",
|
||||
"metrics.log.pid1234.2018-03-07",
|
||||
"metrics.log.pid1234.2018-03-07.10",
|
||||
"metrics.log.pid1234.2018-03-07.51"
|
||||
};
|
||||
ArrayList<String> list = new ArrayList<String>(Arrays.asList(arr));
|
||||
Collections.sort(list, MetricWriter.METRIC_FILE_NAME_CMP);
|
||||
assertEquals(Arrays.asList(key), list);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue