Browse Source

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.
master
Carpenter Lee GitHub 6 years ago
parent
commit
85c844eb9c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 25 deletions
  1. +1
    -1
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java
  2. +35
    -4
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java
  3. +3
    -3
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java
  4. +46
    -17
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java
  5. +27
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/RecordLogTest.java
  6. +54
    -0
      sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricWriterTest.java

+ 1
- 1
sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/CommandCenterLog.java View File

@@ -25,7 +25,7 @@ import java.util.logging.Logger;
public class CommandCenterLog extends LogBase { public class CommandCenterLog extends LogBase {


private static final Logger heliumRecordLog = Logger.getLogger("cspCommandCenterLog"); 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; private static Handler logHandler = null;


static { static {


+ 35
- 4
sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/LogBase.java View File

@@ -24,7 +24,10 @@ import java.util.logging.Logger;
import com.alibaba.csp.sentinel.util.PidUtil; 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 * @author leyou
*/ */
@@ -33,9 +36,21 @@ public class LogBase {
private static final String DIR_NAME = "logs" + File.separator + "csp"; private static final String DIR_NAME = "logs" + File.separator + "csp";
private static final String USER_HOME = "user.home"; private static final String USER_HOME = "user.home";
public static final String LOG_DIR = "csp.sentinel.log.dir"; 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; private static String logBaseDir;


static { static {
try {
init();
} catch (Throwable t) {
t.printStackTrace();
System.exit(-1);
}
}

private static void init() {
// first use -D, then use user home. // first use -D, then use user home.
String logDir = System.getProperty(LOG_DIR); String logDir = System.getProperty(LOG_DIR);


@@ -53,6 +68,19 @@ public class LogBase {
// logBaseDir must end with File.separator // logBaseDir must end with File.separator
logBaseDir = logDir; logBaseDir = logDir;
System.out.println("INFO: log base dir is: " + logBaseDir); 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) { private static String addSeparator(String logDir) {
@@ -61,7 +89,7 @@ public class LogBase {
} }
return logDir; return logDir;
} }
protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) { protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) {
if (detail == null) { if (detail == null) {
return; return;
@@ -73,7 +101,7 @@ public class LogBase {
logger.log(level, detail, params); logger.log(level, detail, params);
} }
} }
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) {
if (detail == null) { if (detail == null) {
return; return;
@@ -93,7 +121,10 @@ public class LogBase {


protected static Handler makeLogger(String logName, Logger heliumRecordLog) { protected static Handler makeLogger(String logName, Logger heliumRecordLog) {
CspFormatter formatter = new CspFormatter(); 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; Handler handler = null;
try { try {
handler = new DateFileLogHandler(fileName + ".%d", 1024 * 1024 * 200, 4, true); handler = new DateFileLogHandler(fileName + ".%d", 1024 * 1024 * 200, 4, true);


+ 3
- 3
sentinel-core/src/main/java/com/alibaba/csp/sentinel/log/RecordLog.java View File

@@ -25,14 +25,14 @@ 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("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; private static Handler logHandler = null;


static { static {
logHandler = makeLogger(FILE_NAME, heliumRecordLog); logHandler = makeLogger(FILE_NAME, heliumRecordLog);
} }
public static void info(String detail, Object... params) { public static void info(String detail, Object... params) {
log(heliumRecordLog, logHandler, Level.INFO, detail, params); log(heliumRecordLog, logHandler, Level.INFO, detail, params);
} }


+ 46
- 17
sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricWriter.java View File

@@ -27,6 +27,7 @@ import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;


import com.alibaba.csp.sentinel.log.LogBase;
import com.alibaba.csp.sentinel.util.PidUtil; import com.alibaba.csp.sentinel.util.PidUtil;
import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.log.RecordLog;
@@ -36,7 +37,7 @@ import com.alibaba.csp.sentinel.log.RecordLog;
* <ol> * <ol>
* <li>metric with the same second should write to the same file;</li> * <li>metric with the same second should write to the same file;</li>
* <li>single file size must be controlled;</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>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> * <li>every metric file is accompanied with an index file, which file name is {@code ${metricFileName}.idx}</li>
* </ol> * </ol>
@@ -47,16 +48,21 @@ public class MetricWriter {


private static final String CHARSET = SentinelConfig.charset(); private static final String CHARSET = SentinelConfig.charset();
public static final String METRIC_BASE_DIR = RecordLog.getLogBaseDir(); 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 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 final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/** /**
* 排除时差干扰 * 排除时差干扰
*/ */
private long timeSecondBase; private long timeSecondBase;
private final StringBuilder sb = new StringBuilder(32);
private String baseDir; private String baseDir;
private String baseFileName; private String baseFileName;
/** /**
@@ -86,7 +92,9 @@ public class MetricWriter {
if (singleFileSize <= 0 || totalFileCount <= 0) { if (singleFileSize <= 0 || totalFileCount <= 0) {
throw new IllegalArgumentException(); 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; this.baseDir = METRIC_BASE_DIR;
File dir = new File(baseDir); File dir = new File(baseDir);
if (!dir.exists()) { if (!dir.exists()) {
@@ -193,7 +201,7 @@ public class MetricWriter {
list.add(file.getAbsolutePath()); list.add(file.getAbsolutePath());
} }
} }
Collections.sort(list, METRIC_FILENAME_CMP);
Collections.sort(list, METRIC_FILE_NAME_CMP);
if (list.isEmpty()) { if (list.isEmpty()) {
return baseDir + baseFileName + "." + dateStr; return baseDir + baseFileName + "." + dateStr;
} }
@@ -209,30 +217,38 @@ public class MetricWriter {
/** /**
* A comparator for metric file name. Metric file name is like: <br/> * A comparator for metric file name. Metric file name is like: <br/>
* <pre> * <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> * </pre>
* <p> * <p>
* File name with the early date is smaller, if date is same, the one with the small file number is smaller. * 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. * 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/> * So the above file names should be sorted as: <br/>
* <pre> * <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> * </pre>
* </p> * </p>
*/ */
private static final class MetricFileNameComparator implements Comparator<String> { private static final class MetricFileNameComparator implements Comparator<String> {
private final String pid = "pid";

@Override @Override
public int compare(String o1, String o2) { public int compare(String o1, String o2) {
String name1 = new File(o1).getName(); String name1 = new File(o1).getName();
String name2 = new File(o2).getName(); String name2 = new File(o2).getName();
String dateStr1 = name1.split("\\.")[2]; String dateStr1 = name1.split("\\.")[2];
String dateStr2 = name2.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 // compare date first
int t = dateStr1.compareTo(dateStr2); int t = dateStr1.compareTo(dateStr2);
@@ -273,7 +289,7 @@ public class MetricWriter {
list.add(file.getAbsolutePath()); list.add(file.getAbsolutePath());
} }
} }
Collections.sort(list, MetricWriter.METRIC_FILENAME_CMP);
Collections.sort(list, MetricWriter.METRIC_FILE_NAME_CMP);
return list; 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. * 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 appName
* @param pid * @param pid
* @return metric file name. * @return metric file name.
@@ -334,7 +353,17 @@ public class MetricWriter {
if (appName == null) { if (appName == null) {
appName = ""; 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;
} }


/** /**


+ 27
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/RecordLogTest.java View File

@@ -19,6 +19,7 @@ import java.io.File;


import com.alibaba.csp.sentinel.log.LogBase; import com.alibaba.csp.sentinel.log.LogBase;
import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.util.PidUtil;


import org.junit.Test; import org.junit.Test;


@@ -61,4 +62,30 @@ public class RecordLogTest {
assertTrue(RecordLog.getLogBaseDir().startsWith(System.getProperty("user.home"))); 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()));
}
}

} }

+ 54
- 0
sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricWriterTest.java View File

@@ -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…
Cancel
Save