- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我们的 spring boot 应用程序,我们使用 logback + GELF将应用程序日志发送到我们可以分析它们的中央日志服务器。是否可以对 spring boot 的访问日志做同样的事情?
如果没有,对于从中央服务器上的多个 spring boot 应用程序收集访问日志,是否有任何其他建议或最佳实践?
最佳答案
好的,经过一番研究我发现了。您需要向 tomcat 添加自定义阀:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory
= new TomcatEmbeddedServletContainerFactory();
GelfAccessLogValve gelfAccessLogValve = new GelfAccessLogValve();
gelfAccessLogValve.setPattern("%h %m %U %I %l %u %t "%r" %s %b");
factory.addContextValves(gelfAccessLogValve);
return factory;
}
我写的valve是基于paluch.biz's valve但不同之处在于它仅依赖于 graylog 的 gelf 客户端。因此,您需要将此依赖项添加到您的 pom:
<dependency>
<groupId>org.graylog2</groupId>
<artifactId>gelfclient</artifactId>
<version>1.4.0</version>
</dependency>
这是阀门代码:
public class GelfAccessLogValve extends AccessLogValve {
private final static Map<Class, String> names = Collections.unmodifiableMap(new HashMap<Class, String>() {
{
put(HeaderElement.class, "Header");
put(CookieElement.class, "Cookie");
put(ResponseHeaderElement.class, "ResponseHeader");
put(SessionAttributeElement.class, "SessionAttribute");
put(RemoteAddrElement.class, "RemoteAddr");
put(LocalAddrElement.class, "LocalAddr");
put(ByteSentElement.class, "ByteSent");
put(ElapsedTimeElement.class, "ElapsedTime");
put(HostElement.class, "Host");
put(ProtocolElement.class, "Protocol");
put(MethodElement.class, "Method");
put(PortElement.class, "LocalPort");
put(QueryElement.class, "Query");
put(RequestElement.class, "Request");
put(FirstByteTimeElement.class, "FirstByteTime");
put(HttpStatusCodeElement.class, "HttpStatusCode");
put(SessionIdElement.class, "SessionId");
put(DateAndTimeElement.class, "DateAndTime");
put(UserElement.class, "User");
put(RequestURIElement.class, "RequestURI");
put(LocalServerNameElement.class, "LocalServerName");
put(ThreadNameElement.class, "ThreadName");
}
});
private String host = "localhost";
private int port = 1234;
private GelfTransport gelfSender;
@Override
public void log(Request request, Response response, long time) {
if (gelfSender == null || !getState().isAvailable() || !getEnabled() || logElements == null || condition != null
&& null != request.getRequest().getAttribute(condition) || conditionIf != null
&& null == request.getRequest().getAttribute(conditionIf)) {
return;
}
/**
* XXX This is a bit silly, but we want to have start and stop time and duration consistent. It would be better to keep
* start and stop simply in the request and/or response object and remove time (duration) from the interface.
*/
long start = request.getCoyoteRequest().getStartTime();
Date date = new Date(start + time);
GelfMessage message = new GelfMessage(request.getMethod() + " " + request.getRequestURI());
message.addAdditionalField("facility", getClass().getSimpleName());
message.setFullMessage(request.getMethod() + " " + request.getRequestURI());
message.setTimestamp(start + time);
message.setLevel(GelfMessageLevel.INFO);
for (int i = 0; i < logElements.length; i++) {
String name = names.get(logElements[i].getClass());
if (name == null) {
continue;
}
CharArrayWriter result = new CharArrayWriter(128);
logElements[i].addElement(result, date, request, response, time);
message.addAdditionalField(name, result.toString());
}
try {
gelfSender.send(message);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private void createSender() {
GelfConfiguration configuration = new GelfConfiguration(host, port);
gelfSender = GelfTransports.create(configuration);
}
@Override
protected synchronized void startInternal() throws LifecycleException {
createSender();
super.startInternal();
}
@Override
protected synchronized void stopInternal() throws LifecycleException {
if (gelfSender != null) {
gelfSender.stop();
gelfSender = null;
}
super.stopInternal();
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
关于spring - 如何通过 GELF 将 spring boot 访问日志发送到远程服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42945201/
这是真的: log(A) + log(B) = log(A * B) [0] 这也是真的吗? O(log(A)) + O(log(B)) = O(log(A * B)) [1] 据我了解 O(f
日志 日志是构建工具的主要界面。如果日志太多,真正的警告和问题容易被隐藏。另一方面,如果出了错,你需要找出相关的信息。Gradle 定义了6个日志级别,如表 18.1,“日志级别”所示。除了那些您通
日志 关键进程日志如下…(将 替换为启动服务的用户,将 替换为计算机名称) NameNode: $ HADOOP_HOME / logs / hadoop- -namenode- .log Da
我正在探索项目的 git 历史 FFMpeg .我在提交之间对每个文件执行了更改 517573a67088b5c7a25c18373434e3448892ee93和 80bb65fafab1d2f5f
我不知道如何在 loggly 中使用正则表达式进行搜索。例如,使用表达式 /24nonstop.+7554/ 记录我想查找的内容. { "level_name": "WARNING", "ex
有没有办法为 API 调用打开日志记录? 我们有一个第三方应用程序在使用我们的商店时遇到问题,希望获得一些调试信息。 ~我已经搜索了 bt 一无所获。 我正在使用 1.7 最佳答案 在一段受控的时间内
我正在尝试获取 SVN 中所有副本/移动/等的固定路径的日志历史记录(如果可能的话,递归地)。实际上,我试图避免 peg revisions ,并将日志应用于路径而不是对象。 svn 手册提出了这个问
如何在命令行中运行 NAnt 脚本并在日志文件中获取每个任务的时间? using nant task or NAnt -buildfile:testscript.build testnanttarg
是否有任何默认方式来记录哪些用户代理访问了您的服务器?我需要编制一份访问我们网站的浏览器列表,以便我们知道我们最能支持什么。 谢谢! 最佳答案 日志CGI.HTTP_USER_AGENT ,也许在 A
我在我的应用程序中使用 Spring 发送电子邮件。 我想在发送电子邮件时记录 imap 服务器操作。 我尝试按如下方式在我的 applicationContext.xml 中实现日志:
我已经运行一个 pod 一个多星期了,从开始到现在没有重启过。但是,我仍然无法查看自它启动以来的日志,它只提供最近两天的日志。容器是否有任何日志轮换策略以及如何根据大小或日期控制轮换? 我尝试了以下命
背景: 我正在设置我的第一个 flex 堆栈,尽管我将开始简单,但是我想确保我从良好的体系结构开始。我最终希望有以下解决方案:托管指标,服务器日志(expressjs APM),单页应用程序监视(AP
常规的 hg log 命令给出每个变更集至少 4 行的输出。例如 changeset: 238:03a214f2a1cf user: My Name date: Th
我在我的项目中使用 Spring iBatis 框架。然后使用 logback 进行记录。然后,在检查日志文件时,我可以看到系统正在使用的数据库...出于安全目的我想隐藏它 这是示例日志.. 12:2
我想使用 hg log 生成一个简短的变更日志,涵盖最新版本的变更。发行版标有“v”前缀,例如“v0.9.1”或“v1.0”。是否可以使用 revsets 选择以“v”开头的最后两个标签之间的范围,不
我是 PHP 的新手,所以如果有一个简单的答案,请原谅我。我在 stackoverflow 中搜索过任何类似的问题,但找不到任何帮助。 我正在开发一个现有的基于 php 的应用程序,我只需要能够将对象
我有一个名为 Radius 的程序可以验证用户登录。运行在CentOS服务器上 日志在/var/log/radius.log 中 它们如下 Mon Jul 24 22:17:08 2017 : Aut
我最近从使用“日志”切换到“日志”。 到目前为止,还不错,但我缺少一项关键功能——在运行时更改最低级别的能力。 在“logging',我可以调用 myLogger.setLevel(logging.I
假设我们有速度关键的系统(例如统计/分析、套接字编程等),我们如何设计跟踪和日志。 更具体地说,日志和跟踪通常会降低性能(即使我们有关闭机制或冗长的扩展机制)。在这种情况下,是否有任何关于如何“放置”
有人知道这个 don't panic 日志包含什么类型的信息吗? /data/dontpanic 然后,我该如何分析这个日志? 最佳答案 我发现这个文件夹在内核崩溃发生后包含了一些 apanic 文件
我是一名优秀的程序员,十分优秀!