简体   繁体   English

如何确定在运行时调用了哪个类的`main`方法?

[英]How can I determine which class's `main` method was invoked at runtime?

I'd like to dynamically determine which class's main method was invoked, in order to allow for an easier to digest combined log file. 我想动态确定哪个类的main方法被调用,以使摘要日志组合更容易消化。

Currently, a single (rotated) log file aggregates all the log output from a number of daemons, but there is no obvious way to determine which daemon the log entry originated from, as all of the daemons use a shared code base, and loggers are created with log4j's getLogger(Something.class) 当前,单个(循环的)日志文件聚合了多个守护程序的所有日志输出,但是没有明显的方法来确定日志条目源自哪个守护程序,因为所有守护程序都使用共享的代码库,并且记录器是使用log4j的getLogger(Something.class)创建

Since we're using a custom Layout class to begin with, actually outputting the information is not an issue, but finding it is. 由于我们使用的是自定义Layout类,因此实际输出信息不是问题,但找到它是一个问题。

One approach that could work as a fallback is defining a property at invocation time and reading that property. 可以作为备用的一种方法是在调用时定义属性并读取该属性。

java -cp ... -Dmain.program=<WHATEVER> MainProgram

However, there's no need to create a new convention if the ability already exists. 但是,如果该功能已经存在,则无需创建新约定。

Update: For my purposes, the following seems to work fine: 更新:就我而言,以下似乎可以正常工作:

import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
public class MyLayout extends PatternLayout {
  private static String _mainClass = null;
  public String format( LoggingEvent event ) {
    String mesg = super.format( event );
    if (mesg.indexOf("$main") > -1) {
      mesg = mesg.replaceAll("\\$main", getMainClass());
    }
    return mesg;
  }
  private static String getMainClass() {
    if (_mainClass == null) {
      StackTraceElement[] elem = new Exception().getStackTrace();
      int offset = elem.length - 1;
      if (elem[offset].getMethodName().equals("main")) {
        _mainClass = elem[offset].getClassName();
      }
      else {
        _mainClass = "<Unknown_Main_Class>";
      }
    }
    return _mainClass;
  }
}

Thanks for the suggestions! 感谢您的建议!

If you only need to do it once you can walk the exception stack and look at the last class/method call. 如果只需要执行一次,则可以遍历异常堆栈并查看最后的类/方法调用。

    StackTraceElement[] elem = new Exception().getStackTrace();
    elem[elem.length - 1].getClassName();

But is error prone. 但是容易出错。 If i load your class via reflection you will see a completely different method at the top. 如果我通过反射加载您的课程,您将在顶部看到完全不同的方法。

You can try M. Jessup variant ( matching a main method signature ) but it will fail if I call a main method from the code too. 您可以尝试M. Jessup变体(匹配主方法签名),但是如果我也从代码中调用主方法,它将失败。

It is a bit hackish, but you could use the static method Thread.getAllStackTraces(). 它有点黑,但是您可以使用静态方法Thread.getAllStackTraces()。 This will get you the stack trace for every live thread in the VM, and assuming the thread that started the application is still alive you could inspect the traces and look for a bottom element whose method signature matched main(String[] args). 这将为您提供VM中每个活动线程的堆栈跟踪,并假设启动应用程序的线程仍然处于活动状态,则可以检查跟踪并查找其方法签名与main(String [] args)相匹配的底部元素。

Veera Sundar has written two articles on how to use Log4j 's Mapped Diagnostic Context (source code for Servlet Filters) http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code/ that might be possible modify for your use case. Veera Sundar已经撰写了两篇有关如何使用Log4j的映射诊断上下文(Servlet过滤器的源代码)的文章, 网址http://veerasundar.com/blog/2009/11/log4j-mdc-mapped-diagnostic-context-example-code /可能会针对您的用例进行修改。

Let your application classes (with the main method) add its class name as a variable which can be written to the log files. 让您的应用程序类(使用main方法)将其类名称添加为可以写入日志文件的变量。

Is it less work than adding a property at runtime? 它比在运行时添加属性要少吗? No, not really but, more elegant 不,不是,但是,更优雅

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确定正在调用哪个Struts动作? - How can I determine which Struts action is being invoked? 如何将作为“值”调用注释的类名和方法传递给注释属性 - How can I pass the class name and method on which the annotaion being invoked as a "value" to the annotation attribute java中可以从另一个类调用类的main()方法吗 - Can a main() method of class be invoked from another class in java 如何检查哪个类调用了方法 - How to check which class invoked a method 当我不知道在启动过程中调用其主方法的类时,可以在main方法中放置一个断点吗? - Can I put a breakpoint in the main method when I do not know the class whose main method is invoked during startup? 我如何调用一个类,该类将获得被调用的类的名称? - How can I call a class which will get the name of the class which is being invoked? 哪个类在运行时实现接口的方法 - Which class implements interface's method at runtime 如果缺少类依赖项,如何确定缺少哪个类? - If a class dependency is missing, how can I determine which class is missing? 如何在线程java应用程序中确定运行时的主类? - How to determine main class at runtime in threaded java application? Mockito:如何替换被测试类调用的类方法? - Mockito: How to replace method of class which is invoked by class under test?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM