java解析日志文件,转为json数组,new Throwable() .getStackTrace()[0].getClassName()使用

本文介绍了一种从特定格式的日志文件中解析并读取数据的方法,使用了Java的JSON解析库来处理日志条目,并展示了如何读取前一天的系统优化日志文件。

此类包括获取上一天日志方法, 关闭文件流方法

技术点: 

JSONObject.fromObject('字符串');

JSONArray.add(JSONObject.fromObject('字符串'));

package com.log;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by macbook-pro-msw on 19/9/17.
 */
public class ReadTest {


    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    private static final Logger logger = Logger.getLogger(new Throwable()
.getStackTrace()[0].getClassName());

    public static void main(String[] args) {
        System.out.println(sdf.format(getTime()));
        JSONArray jsonArray = resolveLogFile();
        System.out.println(jsonArray);

    }


        private static JSONArray resolveLogFile() {
            JSONArray array = new JSONArray();
            File file = new File("/Users/macbook-pro-msw/Documents/tomcat/apache-tomcat-8.5.45"
                    + "/logs/sys-optLog_" + sdf.format(getTime()) + ".log");
            if (file.exists()) {
                InputStreamReader read = null;
                BufferedReader bufferedReader = null;
                try {
                    read = new InputStreamReader(new FileInputStream(file));
                    bufferedReader = new BufferedReader(read);
                    String lineTxt = null;
                    while ((lineTxt = bufferedReader.readLine()) != null) {
                        if (StringUtils.isBlank(lineTxt)) {
                            continue;
                        }
                        byte[] bytes = lineTxt.getBytes("UTF-8");
                        lineTxt = new String(bytes, "UTF-8");
                        lineTxt = lineTxt.substring(lineTxt.indexOf("{"));
                        try {
                            array.add(JSONObject.fromObject(lineTxt));
                        } catch (Exception e) {
                            logger.info("解析optlog文件出错!" + e);
                        }
                    }
                } catch (Exception e) {
                    logger.info("解析optlog文件出错!" + e);
                } finally {
                    closeReaderStream(bufferedReader, read);
                }
            } else {
                logger.info("当日optlog文件不存在!");
            }
            return array;
        }
    private static Date getTime() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, -1);
        return cal.getTime();
    }

    private  static void closeReaderStream(BufferedReader bufferedReader,
                                   InputStreamReader read) {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                logger.info("解析optlog文件出错!" + e);
            }
        }
        if (read != null) {
            try {
                read.close();
            } catch (IOException e) {
                logger.info("解析optlog文件出错!" + e);
            }
        }
    }
}

日志文件: 

sys-optLog_2019-09-17.log 如下

{"name":

"张三","sex":"男","age":22} 

  

    a {"name":"张三","性别":"男","年龄":22}

<think> 我们正在讨论Java中的Throwable.getStackTrace()方法。用户要求详细介绍这个方法及其使用。 根据用户提供的引用,我们可以得知: 引用[1]提到:SUN扩展了ThrowablegetStackTrace()方法,现在返回StackTraceElement数组,每个元素提供位置信息。 引用[2]:Java Throwable getStackTrace()方法在维护方法调用栈时不会抛出异常。 引用[3]:展示了如何使用new Exception().getStackTrace()来查看谁调用了方法,并提到可以限制打印的栈深度。 因此,我们将围绕这些点展开,详细介绍Throwable.getStackTrace()方法。 结构安排: 1. 方法定义和作用 2. 返回的StackTraceElement数组的结构 3. 使用示例 4. 性能注意事项 5. 常见应用场景 6. 相关问题 注意:使用中文,按照要求处理数学公式(虽然这里可能用不到,但如果有表达式要按规则),引用处标注引用标记。 </think>### `Throwable.getStackTrace()` 方法详解 #### 1. **方法定义与作用** ```java public StackTraceElement[] getStackTrace() ``` `getStackTrace()` 是 `java.lang.Throwable` 类的方法,用于**获取异常发生时的调用栈轨迹**。当抛出异常时,JVM 会自动填充栈帧信息[^1]。返回值为 `StackTraceElement[]` 数组,每个元素代表一个栈帧(stack frame),按调用顺序从最新到最旧排列[^2]。 #### 2. **栈帧元素结构** 每个 `StackTraceElement` 包含 4 个关键信息: ```java // 示例输出:com.example.MyClass.myMethod(MyClass.java:25) String className = element.getClassName(); // 类全限定名:com.example.MyClass String methodName = element.getMethodName(); // 方法名:myMethod String fileName = element.getFileName(); // 源文件名:MyClass.java int lineNumber = element.getLineNumber(); // 行号:25 ``` > 📌 注意:行号可能为负数(表示本地方法或编译器优化)[^1] #### 3. **基础使用示例** ```java try { // 可能抛出异常的代码 int result = 1 / 0; } catch (ArithmeticException e) { // 获取并打印调用栈 StackTraceElement[] stackTrace = e.getStackTrace(); for (StackTraceElement element : stackTrace) { System.out.println(element); } } ``` 输出示例: ``` com.example.Test.calculate(Test.java:15) com.example.Test.main(Test.java:8) ``` #### 4. **主动获取调用栈** 无需抛出异常即可获取当前调用栈[^3]: ```java StackTraceElement[] stack = new Throwable().getStackTrace(); // 获取调用者类名(跳过当前方法) String callerClass = stack[1].getClassName(); ``` #### 5. **性能优化技巧** 栈跟踪生成开销较大,需谨慎使用: ```java // ✅ 推荐:先检查日志级别再获取栈信息 if (logger.isDebugEnabled()) { StackTraceElement[] stack = new Throwable().getStackTrace(); logger.debug("Called from: " + stack[1].getMethodName()); } // ❌ 避免:深度遍历整个调用栈(Android示例限制到5层)[^3] for (int i = 0; i < Math.min(stack.length, 5); i++) { System.out.println(stack[i]); } ``` #### 6. **高级应用场景** **场景 1:动态日志增强** ```java public static void logWithContext(Logger logger, String msg) { StackTraceElement caller = new Throwable().getStackTrace()[1]; String context = caller.getFileName() + ":" + caller.getLineNumber(); logger.info(context + " | " + msg); } ``` **场景 2:权限校验** ```java public void sensitiveOperation() { StackTraceElement caller = new Throwable().getStackTrace()[1]; if (!caller.getClassName().startsWith("com.trusted.")) { throw new SecurityException("非法调用来源"); } // 执行操作... } ``` #### 7. **JVM 参数调优** 通过 JVM 参数控制栈信息深度: ```bash # 限制栈轨迹深度为 100java -XX:MaxJavaStackTraceDepth=100 MyApp # 完全禁用栈轨迹填充(提升性能) java -XX:-OmitStackTraceInFastThrow MyApp ``` ### 注意事项 1. **行号准确性**: - Release 模式编译的代码可能缺失行号(`-g:none` 编译选项) - JIT 优化可能导致行号偏移 2. **安全限制**: SecurityManager 可能阻止获取栈信息 3. **Android 差异**: Android 的 `getStackTrace()` 返回的数组可能比标准 Java 更短[^3] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值