always generate log file

This commit is contained in:
金戟 2021-04-05 11:56:06 +08:00
parent 93cdef1d6c
commit 01e9890234
9 changed files with 129 additions and 20 deletions

View File

@ -3,7 +3,7 @@ package com.alibaba.demo.java2kotlin
import java.io.File
import java.io.IOException
object PathUtil {
object PathDemo {
fun deleteRecursively(file: File) {
if (!file.exists()) {

View File

@ -5,7 +5,7 @@ import com.alibaba.testable.core.matcher.InvokeVerifier.verify
import org.junit.jupiter.api.Test
import java.io.File
class PathUtilTest {
class PathDemoTest {
class Mock {
@MockMethod
@ -42,7 +42,7 @@ class PathUtilTest {
@Test
fun should_mock_java_method_invoke_in_kotlin() {
PathUtil.deleteRecursively(File("/a/b/"))
PathDemo.deleteRecursively(File("/a/b/"))
verify("listFiles").withTimes(2)
verify("delete").withTimes(4)
}

View File

@ -3,6 +3,7 @@ package com.alibaba.testable.agent;
import com.alibaba.testable.agent.transformer.TestableClassTransformer;
import com.alibaba.testable.agent.util.GlobalConfig;
import com.alibaba.testable.core.model.MockScope;
import com.alibaba.testable.core.util.LogUtil;
import com.alibaba.ttl.threadpool.agent.TtlAgent;
import java.lang.instrument.Instrumentation;
@ -23,6 +24,7 @@ public class PreMain {
private static boolean enhanceThreadLocal = false;
public static void premain(String agentArgs, Instrumentation inst) {
GlobalConfig.setupLogRootPath();
parseArgs(agentArgs);
if (enhanceThreadLocal) {
// add transmittable thread local transformer
@ -30,6 +32,7 @@ public class PreMain {
}
// add testable mock transformer
inst.addTransformer(new TestableClassTransformer());
cleanup();
}
private static void parseArgs(String args) {
@ -60,4 +63,13 @@ public class PreMain {
}
}
private static void cleanup() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LogUtil.cleanup();
}
});
}
}

View File

@ -211,7 +211,7 @@ public class BytecodeUtil {
return;
}
try {
String dumpFile = StringUtil.joinPath(dumpPath,
String dumpFile = PathUtil.join(dumpPath,
className.replace(SLASH, DOT).replace(DOLLAR, UNDERLINE) + ".class");
LogUtil.verbose("Dump class: " + dumpFile);
FileOutputStream stream = new FileOutputStream(dumpFile);

View File

@ -14,6 +14,7 @@ public class GlobalConfig {
private static final String MUTE = "mute";
private static final String DEBUG = "debug";
private static final String VERBOSE = "verbose";
private static final String USER_DIR = "user.dir";
private static String dumpPath = null;
private static String pkgPrefix = null;
@ -56,4 +57,9 @@ public class GlobalConfig {
public static void setDefaultMockScope(MockScope scope) {
defaultMockScope = scope;
}
public static void setupLogRootPath() {
LogUtil.setGlobalLogPath(
PathUtil.getFirstLevelFolder(System.getProperty(USER_DIR), Object.class.getResource("/").getPath()));
}
}

View File

@ -0,0 +1,31 @@
package com.alibaba.testable.agent.util;
import java.io.File;
public class PathUtil {
/**
* Join a path text and a file name to full file path
* @param folder path text
* @param file file name
* @return joined full file path
*/
public static String join(String folder, String file) {
return (folder.endsWith(File.separator) ? folder : (folder + File.separator)) + file;
}
/**
* Get the absolute path of the first sub-folder from root folder to target path
* @param rootFolder specify root folder path
* @param targetPath any sub path inside root folder
* @return first sub-folder path
*/
public static String getFirstLevelFolder(String rootFolder, String targetPath) {
if (!targetPath.startsWith(rootFolder) || targetPath.length() <= rootFolder.length() + 1) {
return "";
}
char separator = targetPath.charAt(rootFolder.length());
int pos = targetPath.indexOf(separator, rootFolder.length() + 1);
return pos > 0 ? targetPath.substring(0, pos) : "";
}
}

View File

@ -1,7 +1,5 @@
package com.alibaba.testable.agent.util;
import java.io.File;
/**
* @author flin
*/
@ -21,14 +19,4 @@ public class StringUtil {
return sb.toString();
}
/**
* join a path text and a file name to full file path
* @param folder path text
* @param file file name
* @return joined full file path
*/
public static String joinPath(String folder, String file) {
return (folder.endsWith(File.separator) ? folder : (folder + File.separator)) + file;
}
}

View File

@ -0,0 +1,17 @@
package com.alibaba.testable.agent.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PathUtilTest {
@Test
void should_get_sub_folder() {
assertEquals("/ab/cd", PathUtil.getFirstLevelFolder("/ab", "/ab/cd/ef/gh"));
assertEquals("c:\\ab\\cd", PathUtil.getFirstLevelFolder("c:\\ab", "c:\\ab\\cd\\ef\\gh"));
assertEquals("", PathUtil.getFirstLevelFolder("/ab", "/ab"));
assertEquals("", PathUtil.getFirstLevelFolder("/ab/cd", "/ab"));
}
}

View File

@ -2,34 +2,55 @@ package com.alibaba.testable.core.util;
import com.alibaba.testable.core.model.LogLevel;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
/**
* @author flin
*/
public class LogUtil {
private static final String TESTABLE_AGENT_LOG = "testable-agent.log";
private static LogLevel defaultLogLevel = LogLevel.DEFAULT;
private static LogLevel currentLogLevel = LogLevel.DEFAULT;
private static FileOutputStream logFileStream = null;
public static void verbose(String msg, Object... args) {
if (isVerboseEnabled()) {
System.out.println(String.format("[VERBOSE] " + msg, args));
String text = String.format(msg + "\n", args);
System.out.print("[VERBOSE] ");
System.out.print(text);
write("[TIP] ");
write(text);
}
}
public static void diagnose(String msg, Object... args) {
String text = String.format(msg + "\n", args);
if (currentLogLevel.level >= LogLevel.ENABLE.level) {
System.out.println(String.format("[DIAGNOSE] " + msg, args));
System.out.print("[DIAGNOSE] ");
System.out.print(text);
}
write("[INFO] ");
write(text);
}
public static void warn(String msg, Object... args) {
String text = String.format("[WARN] " + msg + "\n", args);
if (currentLogLevel.level >= LogLevel.DEFAULT.level) {
System.err.println(String.format("[WARN] " + msg, args));
System.err.print(text);
}
write(text);
}
public static void error(String msg, Object... args) {
System.err.println(String.format("[ERROR] " + msg, args));
String text = String.format("[ERROR] " + msg + "\n", args);
System.err.print(text);
write(text);
}
/**
@ -52,4 +73,38 @@ public class LogUtil {
currentLogLevel = defaultLogLevel;
}
public static void setGlobalLogPath(String logFolderPath) {
if (logFolderPath.isEmpty()) {
return;
}
String logFilePath = logFolderPath + File.separator + TESTABLE_AGENT_LOG;
try {
logFileStream = new FileOutputStream(logFilePath);
diagnose("Start at %s", new Date().toString());
} catch (FileNotFoundException e) {
warn("Failed to create log file %s", logFilePath);
}
}
public static void cleanup() {
try {
if (logFileStream != null) {
diagnose("Completed at %s", new Date().toString());
logFileStream.flush();
logFileStream.close();
}
} catch (IOException e) {
warn("Log file is not closed properly");
}
}
private static void write(String text) {
try {
if (logFileStream != null) {
logFileStream.write(text.getBytes());
}
} catch (IOException e) {
// ignore
}
}
}