未验证 提交 bc92d78e 编写于 作者: V Vlad Ilyushchenko 提交者: GitHub

chore(log): log configuration can be sources from Env (#644)

上级 2c73da5d
...@@ -47,13 +47,6 @@ public class LogFactory implements Closeable { ...@@ -47,13 +47,6 @@ public class LogFactory implements Closeable {
private static final String EMPTY_STR = ""; private static final String EMPTY_STR = "";
private static final CharSequenceHashSet reserved = new CharSequenceHashSet(); private static final CharSequenceHashSet reserved = new CharSequenceHashSet();
private static final LengthDescendingComparator LDC = new LengthDescendingComparator(); private static final LengthDescendingComparator LDC = new LengthDescendingComparator();
static {
reserved.add("scope");
reserved.add("class");
reserved.add("level");
}
private final CharSequenceObjHashMap<ScopeConfiguration> scopeConfigMap = new CharSequenceObjHashMap<>(); private final CharSequenceObjHashMap<ScopeConfiguration> scopeConfigMap = new CharSequenceObjHashMap<>();
private final ObjList<ScopeConfiguration> scopeConfigs = new ObjList<>(); private final ObjList<ScopeConfiguration> scopeConfigs = new ObjList<>();
private final ObjHashSet<LogWriter> jobs = new ObjHashSet<>(); private final ObjHashSet<LogWriter> jobs = new ObjHashSet<>();
...@@ -71,62 +64,10 @@ public class LogFactory implements Closeable { ...@@ -71,62 +64,10 @@ public class LogFactory implements Closeable {
this.clock = clock; this.clock = clock;
} }
@SuppressWarnings("rawtypes")
public static Log getLog(Class clazz) {
return getLog(clazz.getName());
}
public static Log getLog(CharSequence key) {
if (!INSTANCE.configured) {
configureFromSystemProperties(INSTANCE, null);
}
return INSTANCE.create(key);
}
public static void configureFromSystemProperties(WorkerPool workerPool) {
configureFromSystemProperties(INSTANCE, workerPool);
}
public static void configureFromSystemProperties(LogFactory factory) {
configureFromSystemProperties(factory, null);
}
public static void configureFromSystemProperties(LogFactory factory, WorkerPool workerPool) {
String conf = System.getProperty(CONFIG_SYSTEM_PROPERTY);
if (conf == null) {
conf = DEFAULT_CONFIG;
}
try (InputStream is = LogFactory.class.getResourceAsStream(conf)) {
if (is != null) {
Properties properties = new Properties();
properties.load(is);
configureFromProperties(factory, properties, workerPool);
} else {
File f = new File(conf);
if (f.canRead()) {
try (FileInputStream fis = new FileInputStream(f)) {
Properties properties = new Properties();
properties.load(fis);
configureFromProperties(factory, properties, workerPool);
}
} else {
factory.configureDefaultWriter();
}
}
} catch (IOException e) {
if (!DEFAULT_CONFIG.equals(conf)) {
throw new LogError("Cannot read " + conf, e);
} else {
factory.configureDefaultWriter();
}
}
factory.startThread();
}
public static void configureFromProperties(LogFactory factory, Properties properties, WorkerPool workerPool) { public static void configureFromProperties(LogFactory factory, Properties properties, WorkerPool workerPool) {
factory.workerPool = workerPool; factory.workerPool = workerPool;
String writers = properties.getProperty("writers"); String writers = getProperty(properties, "writers");
if (writers == null) { if (writers == null) {
factory.configured = true; factory.configured = true;
...@@ -135,7 +76,7 @@ public class LogFactory implements Closeable { ...@@ -135,7 +76,7 @@ public class LogFactory implements Closeable {
String s; String s;
s = properties.getProperty("queueDepth"); s = getProperty(properties, "queueDepth");
if (s != null && s.length() > 0) { if (s != null && s.length() > 0) {
try { try {
factory.setQueueDepth(Numbers.parseInt(s)); factory.setQueueDepth(Numbers.parseInt(s));
...@@ -144,7 +85,7 @@ public class LogFactory implements Closeable { ...@@ -144,7 +85,7 @@ public class LogFactory implements Closeable {
} }
} }
s = properties.getProperty("recordLength"); s = getProperty(properties, "recordLength");
if (s != null && s.length() > 0) { if (s != null && s.length() > 0) {
try { try {
factory.setRecordLength(Numbers.parseInt(s)); factory.setRecordLength(Numbers.parseInt(s));
...@@ -163,113 +104,56 @@ public class LogFactory implements Closeable { ...@@ -163,113 +104,56 @@ public class LogFactory implements Closeable {
factory.bind(); factory.bind();
} }
@SuppressWarnings("rawtypes") public static void configureFromSystemProperties(LogFactory factory) {
private static LogWriterConfig createWriter(final Properties properties, String w) { configureFromSystemProperties(factory, null);
final String writer = "w." + w + '.'; }
final String clazz = properties.getProperty(writer + "class");
final String levelStr = properties.getProperty(writer + "level");
final String scope = properties.getProperty(writer + "scope");
if (clazz == null) {
return null;
}
final Class<?> cl;
final Constructor constructor;
try {
cl = Class.forName(clazz);
constructor = cl.getDeclaredConstructor(RingQueue.class, SCSequence.class, int.class);
} catch (ClassNotFoundException e) {
throw new LogError("Class not found " + clazz, e);
} catch (NoSuchMethodException e) {
throw new LogError("Constructor(RingQueue, Sequence, int) expected: " + clazz, e);
}
int level = 0;
if (levelStr != null) {
for (String s : levelStr.split(",")) {
switch (s.toUpperCase()) {
case "DEBUG":
level |= LogLevel.LOG_LEVEL_DEBUG;
break;
case "INFO":
level |= LogLevel.LOG_LEVEL_INFO;
break;
case "ERROR":
level |= LogLevel.LOG_LEVEL_ERROR;
break;
default:
throw new LogError("Unknown level: " + s);
}
}
}
if (System.getProperty(DEBUG_TRIGGER) != null) { public static void configureFromSystemProperties(LogFactory factory, WorkerPool workerPool) {
level = level | LogLevel.LOG_LEVEL_DEBUG; String conf = System.getProperty(CONFIG_SYSTEM_PROPERTY);
if (conf == null) {
conf = DEFAULT_CONFIG;
} }
try (InputStream is = LogFactory.class.getResourceAsStream(conf)) {
return new LogWriterConfig(scope == null ? EMPTY_STR : scope, level, (ring, seq, level1) -> { if (is != null) {
try { Properties properties = new Properties();
LogWriter w1 = (LogWriter) constructor.newInstance(ring, seq, level1); properties.load(is);
configureFromProperties(factory, properties, workerPool);
for (String n : properties.stringPropertyNames()) { } else {
if (n.startsWith(writer)) { File f = new File(conf);
String p = n.substring(writer.length()); if (f.canRead()) {
try (FileInputStream fis = new FileInputStream(f)) {
if (reserved.contains(p)) { Properties properties = new Properties();
continue; properties.load(fis);
} configureFromProperties(factory, properties, workerPool);
try {
Field f = cl.getDeclaredField(p);
if (f.getType() == String.class) {
Unsafe.getUnsafe().putObject(w1, Unsafe.getUnsafe().objectFieldOffset(f), properties.getProperty(n));
}
} catch (Exception e) {
throw new LogError("Unknown property: " + n, e);
}
} }
} else {
factory.configureDefaultWriter();
} }
return w1;
} catch (Exception e) {
throw new LogError("Error creating log writer", e);
} }
}); } catch (IOException e) {
} if (!DEFAULT_CONFIG.equals(conf)) {
throw new LogError("Cannot read " + conf, e);
/** } else {
* Converts fully qualified class name into an abbreviated form: factory.configureDefaultWriter();
* com.questdb.mp.Sequence -> c.n.m.Sequence
*
* @param key typically class name
* @return abbreviated form of key
*/
private static CharSequence compressScope(CharSequence key) {
StringBuilder builder = new StringBuilder();
char c = 0;
boolean pick = true;
int z = 0;
for (int i = 0, n = key.length(); i < n; i++) {
char a = key.charAt(i);
if (a == '.') {
if (!pick) {
builder.append(c).append('.');
pick = true;
}
} else if (pick) {
c = a;
z = i;
pick = false;
} }
} }
factory.startThread();
}
for (; z < key.length(); z++) { public static void configureFromSystemProperties(WorkerPool workerPool) {
builder.append(key.charAt(z)); configureFromSystemProperties(INSTANCE, workerPool);
} }
builder.append(' '); @SuppressWarnings("rawtypes")
public static Log getLog(Class clazz) {
return getLog(clazz.getName());
}
return builder; public static Log getLog(CharSequence key) {
if (!INSTANCE.configured) {
configureFromSystemProperties(INSTANCE, null);
}
return INSTANCE.create(key);
} }
public void add(final LogWriterConfig config) { public void add(final LogWriterConfig config) {
...@@ -284,6 +168,15 @@ public class LogFactory implements Closeable { ...@@ -284,6 +168,15 @@ public class LogFactory implements Closeable {
scopeConf.add(config); scopeConf.add(config);
} }
public void assign(WorkerPool workerPool) {
for (int i = 0, n = jobs.size(); i < n; i++) {
workerPool.assign(jobs.get(i));
}
if (this.workerPool == null) {
this.workerPool = workerPool;
}
}
public void bind() { public void bind() {
if (configured) { if (configured) {
return; return;
...@@ -400,13 +293,121 @@ public class LogFactory implements Closeable { ...@@ -400,13 +293,121 @@ public class LogFactory implements Closeable {
workerPool.start(null); workerPool.start(null);
} }
public void assign(WorkerPool workerPool) { private static String getProperty(final Properties properties, String key) {
for (int i = 0, n = jobs.size(); i < n; i++) { final String envValue = System.getenv("QDB_LOG_" + key.replace('.', '_').toUpperCase());
workerPool.assign(jobs.get(i)); if (envValue == null) {
return properties.getProperty(key);
} }
if (this.workerPool == null) { return envValue;
this.workerPool = workerPool; }
@SuppressWarnings("rawtypes")
private static LogWriterConfig createWriter(final Properties properties, String w) {
final String writer = "w." + w + '.';
final String clazz = getProperty(properties, writer + "class");
final String levelStr = getProperty(properties, writer + "level");
final String scope = getProperty(properties, writer + "scope");
if (clazz == null) {
return null;
}
final Class<?> cl;
final Constructor constructor;
try {
cl = Class.forName(clazz);
constructor = cl.getDeclaredConstructor(RingQueue.class, SCSequence.class, int.class);
} catch (ClassNotFoundException e) {
throw new LogError("Class not found " + clazz, e);
} catch (NoSuchMethodException e) {
throw new LogError("Constructor(RingQueue, Sequence, int) expected: " + clazz, e);
}
int level = 0;
if (levelStr != null) {
for (String s : levelStr.split(",")) {
switch (s.toUpperCase()) {
case "DEBUG":
level |= LogLevel.LOG_LEVEL_DEBUG;
break;
case "INFO":
level |= LogLevel.LOG_LEVEL_INFO;
break;
case "ERROR":
level |= LogLevel.LOG_LEVEL_ERROR;
break;
default:
throw new LogError("Unknown level: " + s);
}
}
}
if (System.getProperty(DEBUG_TRIGGER) != null) {
level = level | LogLevel.LOG_LEVEL_DEBUG;
} }
return new LogWriterConfig(scope == null ? EMPTY_STR : scope, level, (ring, seq, level1) -> {
try {
LogWriter w1 = (LogWriter) constructor.newInstance(ring, seq, level1);
for (String n : properties.stringPropertyNames()) {
if (n.startsWith(writer)) {
String p = n.substring(writer.length());
if (reserved.contains(p)) {
continue;
}
try {
Field f = cl.getDeclaredField(p);
if (f.getType() == String.class) {
Unsafe.getUnsafe().putObject(w1, Unsafe.getUnsafe().objectFieldOffset(f), getProperty(properties, n));
}
} catch (Exception e) {
throw new LogError("Unknown property: " + n, e);
}
}
}
return w1;
} catch (Exception e) {
throw new LogError("Error creating log writer", e);
}
});
}
/**
* Converts fully qualified class name into an abbreviated form:
* com.questdb.mp.Sequence -> c.n.m.Sequence
*
* @param key typically class name
* @return abbreviated form of key
*/
private static CharSequence compressScope(CharSequence key) {
StringBuilder builder = new StringBuilder();
char c = 0;
boolean pick = true;
int z = 0;
for (int i = 0, n = key.length(); i < n; i++) {
char a = key.charAt(i);
if (a == '.') {
if (!pick) {
builder.append(c).append('.');
pick = true;
}
} else if (pick) {
c = a;
z = i;
pick = false;
}
}
for (; z < key.length(); z++) {
builder.append(key.charAt(z));
}
builder.append(' ');
return builder;
} }
private void configureDefaultWriter() { private void configureDefaultWriter() {
...@@ -607,4 +608,10 @@ public class LogFactory implements Closeable { ...@@ -607,4 +608,10 @@ public class LogFactory implements Closeable {
} }
} }
} }
static {
reserved.add("scope");
reserved.add("class");
reserved.add("level");
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册