我有一个实例化多个线程的应用程序。每个服务都具有相同的log4j2配置,可写入日志和套接字appender。 我需要在所有日志和套接字输出中获取主机信息,但使用
InetAddress addr = InetAddress.getLocalHost();
ThreadContext.put("Host", addr.getHostName());
我只在" main"中收到该信息。线程。
在某些异步模型中,可以将工作委托给多个线程,而从概念上讲,这项工作共享相同的上下文。在这样的模型中,将上下文数据存储在ThreadLocal变量中是不方便或不可取的。用户可以配置ContextDataInjectorFactory以提供自定义ContextDataInjector对象,以便使用来自任意上下文的上下文数据初始化日志事件。
我应该创建一个自定义ContextDataInjector,但我无法对其进行编码。 我编码了这个
List<Property> propertiesTest = new ArrayList<>();
propertiesTest.add(Property.createProperty("Host", "test"));
StringMap reusabletest = null;
ContextDataInjector prueba = ContextDataInjectorFactory.createInjector();
prueba.injectContextData(propertiesTest, reusabletest);
但它不起作用......
另一种方法是以这种方式实现ContextDataInjector:
public class Log4j2Manager implements ContextDataInjector
{
private static Log4j2Configuration config;
private static final String PROPERTIES_PATH = "/etc//Log4j2Manager/Log4j2Manager.properties";
private final static Logger LOG = LogManager.getLogger(Log4j2Manager.class);
private static Log4j2slave[] workers = null;
public Log4j2Manager(String configPath) throws Exception
{
List<Property> propertiesTest = new ArrayList<>();
propertiesTest.add(Property.createProperty("Host", "test"));
StringMap reusableTest = null;
injectContextData(propertiesTest, reusableTest);
workers = new Log4j2slave[config.NumWorkers];
for (int i = 0; i < workers.length; i++)
{
workers[i] = new Log4j2slave(i);
Thread.sleep(1000);
}
....
}
....
@Override
public StringMap injectContextData(List<Property> properties, StringMap reusable)
{
if (properties == null || properties.isEmpty())
{
// assume context data is stored in a copy-on-write data structure
// that is safe to pass to another thread
return (StringMap) rawContextData();
}
// first copy configuration properties into the result
ThreadContextDataInjector.copyProperties(properties, reusable);
// then copy context data key-value pairs (may overwrite configuration
// properties)
reusable.putAll(rawContextData());
return reusable;
}
@Override
public ReadOnlyStringMap rawContextData() {
// TODO Auto-generated method stub
return null;
}
但它返回零点异常。 有什么建议吗?
最好的问候
答案 0 :(得分:1)
您没有提供堆栈跟踪,但我怀疑nullpointer异常是由return s.join(encdic.get(c,c) for c in plaintext)
的实现引起的。它不能返回rawContextData()
。
请参阅null
界面的Log4j2 built-in implementations,了解从此方法返回的内容。
要安装自定义上下文数据注入器,您需要在系统属性ContextDataInjector
中指定实现的完全限定类。请参阅ContextDataInjectorFactory。
答案 1 :(得分:0)
最后我直接打电话给我,我做了一个测试。 使用
ThreadContext.put("Host", addr.getHostName())
我可以得到&#34;主持人&#34;只有主要的,而如果我避免这种结构,我没有任何价值,也没有进入主要 我不明白错误在哪里。
InetAddress addr = InetAddress.getLocalHost();
ThreadContext.put("Host", addr.getHostName());
List<Property> properties = new ArrayList<>();
properties.add(Property.createProperty("Host", "test"));
StringMap reusable = null;
ContextDataInjector prueba = new ForGarbageFreeThreadContextMap();
prueba.injectContextData(properties, reusable);
Log4j2Manager Log4j2Man = new Log4j2Manager(propertiesPath);
Log4j2Man.Start();