- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我的 java 项目,我正在使用 java logging api。我想使用属性文件记录所有内容。
在使用此文件 (log.properties) 之前,我在 java 代码中配置了我的 onwn 格式化程序。 (见下文)
现在我想在属性文件中配置我自己的格式,而不是 java 代码。有人知道怎么做吗?
Formatter formatter = new Formatter() {
@Override
public String format(LogRecord arg0) {
StringBuilder b = new StringBuilder();
b.append(new Date());
b.append(" ");
b.append(arg0.getSourceClassName());
b.append(" ");
b.append(arg0.getSourceMethodName());
b.append(" ");
b.append(arg0.getLevel());
b.append(" ");
b.append(arg0.getMessage());
b.append(System.getProperty("line.separator"));
return b.toString();
}
};
java代码中的格式化
..... .....
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.FileHandler.level=WARNING
**java.util.logging.??? = how can i configure my own formater in the property file with this information: data, clasename, methodename, level .etc.****
log.propties 中的格式化程序
最佳答案
编写您自己的接受格式字符串的 Formatter。
在 logging.properties 文件中配置格式化程序。例如:
java.util.logging.ConsoleHandler.formatter = my.util.logging.CustomFormatter
my.util.logging.CustomFormatter.format = %t %L: %E %m
my.util.logging.CustomFormatter.date.format = ddMMMyyyy HH:mm:ss
# logger.log(Level.INFO, "INFO message.");
# produces the following log message:
# 18Aug2013 13:04:19 INFO: (LoggingLevelDemo.java:34) INFO message.
如果编写这样的 Formatter 看起来令人生畏,那么可以从这里开始:
package my.util.logging;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.Format;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.logging.Formatter;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
* A {@link Formatter} that may be customized in a {@code logging.properties} file. The syntax of the property
* {@code my.util.logging.CustomFormatter.format} specifies the output. A newline will be appended to the string and
* the following special characters will be expanded (case sensitive):-
* <ul>
* <li>{@code %m} - message</li>
* <li>{@code %L} - log level</li>
* <li>{@code %n} - name of the logger</li>
* <li>{@code %t} - a timestamp (in ISO-8601 "yyyy-MM-dd HH:mm:ss.SSS" format)</li>
* <li>{@code %M} - source method name (if available, otherwise "?")</li>
* <li>{@code %c} - source class name (if available, otherwise "?")</li>
* <li>{@code %C} - source simple class name (if available, otherwise "?")</li>
* <li>{@code %T} - thread ID</li>
* <li>{@code %E} - (Filename.java:linenumber) Slow to generate Eclipse format</li>
* </ul>
* The default format is {@value #DEFAULT_FORMAT}. Curly brace characters are not allowed.
*
* Based on http://javablog.co.uk/2008/07/12/logging-with-javautillogging/
* %E Eclipse format was added with flag to avoid Stack trace generation if Eclipse format not used.
*
* @author Samuel Halliday
* @author Ryan Ripken
*/
public class CustomFormatter extends Formatter
{
// milliseconds can be nice for rough performance numbers
public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS Z";
private static final DateFormat defaultDateFormat = new SimpleDateFormat(DATE_FORMAT);
// private static final String USACE_DATE_FORMAT = "yyyyMMdd HHmmss Z";
public static final String DEFAULT_FORMAT = "%t %L: %E %m";
protected static final StackTraceElement nullElement = new StackTraceElement("?", "?", "?", -1);
private final MessageFormat messageFormat;
private final boolean[] needsArg;
private final DateFormat dateFormat;
public CustomFormatter()
{
super();
LogManager logManager = LogManager.getLogManager();
String classname = getClass().getName();
// load the format from logging.properties
String dateFormatKey = classname + ".date.format";
String strDateFormat = logManager.getProperty(dateFormatKey);
if (strDateFormat != null) {
dateFormat = new SimpleDateFormat(strDateFormat);
} else {
dateFormat = defaultDateFormat;
}
String dateFormatTimeZoneKey = classname + ".date.timezone";
String strDateFormatTimeZone = logManager
.getProperty(dateFormatTimeZoneKey);
if (strDateFormatTimeZone != null) {
dateFormat.setTimeZone(TimeZone.getTimeZone(strDateFormatTimeZone));
}
String propName = classname + ".format";
String format = logManager.getProperty(propName);
if (format == null || format.trim().length() == 0) {
format = DEFAULT_FORMAT;
}
if (format.contains("{") || format.contains("}")) {
throw new IllegalArgumentException("curly braces not allowed");
}
// convert it into the MessageFormat form
format = format.replace("%L", "{0}")
.replace("%m", "{1}")
.replace("%M", "{2}")
.replace("%t", "{3}")
.replace("%c", "{4}")
.replace("%T", "{5}")
.replace("%n", "{6}")
.replace("%C", "{7}")
.replace("%E", "{8}") +
"\n";
messageFormat = new MessageFormat(format);
Format[] formatsByArgumentIndex = messageFormat.getFormatsByArgumentIndex();
needsArg = new boolean[9];
for (int i = 0; i < formatsByArgumentIndex.length; i++) {
needsArg[i] = format.contains("{" + i + "}");
}
}
@Override
public String format(LogRecord record)
{
String[] arguments = new String[9];
// This is a StringBuffer instead of StringBuilder so that
// it can be re-used for the messageFormat.format calls.
// It is, hopefully, slightly oversized so that it won't
// have to be enlarged...
StringBuffer sb = new StringBuffer(256);
if (needsArg[0]) {
// %L
arguments[0] = record.getLevel().toString();
}
if (needsArg[1]) {
// %m
sb = formatMessage(record, sb);
sb = getThrowableMessage(record, sb); // maybe this should have been its own flag?
arguments[1] = sb.toString();
}
if (needsArg[2]) {
// %M
arguments[2] = record.getSourceMethodName();
} else {
arguments[2] = "?";
}
if (needsArg[3]) {
// %t
sb.delete(0, sb.length()); // re-use
Date date = new Date(record.getMillis());
FieldPosition fieldPos = new FieldPosition(0);
synchronized (dateFormat) {
sb = dateFormat.format(date, sb, fieldPos);
}
arguments[3] = sb.toString();
}
if (needsArg[4] || needsArg[7]) {
// %c
arguments[4] = record.getSourceClassName();
} else {
arguments[4] = "?";
}
if (needsArg[5]) {
// %T
arguments[5] = Integer.toString(record.getThreadID());
}
if (needsArg[6]) {
// %n
arguments[6] = record.getLoggerName();
}
if (needsArg[7]) {
// %C
int start = arguments[4].lastIndexOf('.') + 1;
if (start > 0 && start < arguments[4].length()) {
arguments[7] = arguments[4].substring(start);
} else {
arguments[7] = arguments[4];
}
}
if (needsArg[8]) {
// %E Expensive Eclipse Format
sb.delete(0, sb.length()); // reuse buffer
getEclipseFormat(sb); // gets a stackTrace to generate.
arguments[8] = sb.toString();
} else {
arguments[8] = "(?:?)";
}
sb.delete(0, sb.length()); //reuse buffer
FieldPosition fieldPos = new FieldPosition(0);
synchronized (messageFormat) {
// messageFormat.format only calls into
// messageFormat.format(arguments, new StringBuffer(), new FieldPosition(0)).toString();
// we already have a StringBuffer laying around. We should reuse it.
//return messageFormat.format(arguments);
sb = messageFormat.format(arguments, sb, fieldPos);
}
return sb.toString();
}
/**
* Localize and format the message string from a log record.
* <p>
* The message string is first localized to a format string using the record's ResourceBundle. (If there is no
* ResourceBundle, or if the message key is not found, then the key is used as the format string.) The format String
* uses java.text style formatting.
* <ul>
* <li>If there are no parameters, no formatter is used.
* <li>Otherwise, if the string contains "{0" then java.text.MessageFormat is used to format the string.
* <li>Otherwise no formatting is performed.
* </ul>
* <p>
*
* @param record the log record containing the raw message
* @param result the StringBuffer where the message text is to be appended
* @return StringBuffer where the message text was appended
*/
public synchronized StringBuffer formatMessage(LogRecord record, StringBuffer result)
{
// This is the default formatMessage implementation from
// java.util.logging.Formatter except that it has been
// modified to operate on the passed in StringBuffer.
String format = record.getMessage();
java.util.ResourceBundle catalog = record.getResourceBundle();
if (catalog != null) {
try {
format = catalog.getString(record.getMessage());
} catch (java.util.MissingResourceException ex) {
// Drop through. Use record message as format
format = record.getMessage();
}
}
// Do the formatting.
try {
Object parameters[] = record.getParameters();
if (parameters == null || parameters.length == 0) {
// No parameters. Just return format string.
result.append(format);
} else if (format.indexOf("{0") >= 0 ||
format.indexOf("{1") >= 0 ||
format.indexOf("{2") >= 0 ||
format.indexOf("{3") >= 0) {
// Is is a java.text style format?
// Ideally we could match with
// Pattern.compile("\\{\\d").matcher(format).find())
// However the cost is 14% higher, so we cheaply check for
// 1 of the first 4 parameters
MessageFormat temp = new MessageFormat(format);
temp.format(parameters, result, new FieldPosition(0)); // this appends to sb
} else {
result.append(format);
}
} catch (Exception ex) {
// Formatting failed: use localized format string.
result.append(format);
}
return result;
}
protected StringBuffer getThrowableMessage(LogRecord record, StringBuffer sb)
{
Throwable thrown = record.getThrown();
if (thrown != null) {
PrintWriter pw = null;
try {
StringWriter sw = new StringWriter();
pw = new PrintWriter(sw);
record.getThrown().printStackTrace(pw);
pw.flush();
sb.append('\n');
sb.append(sw.toString());
} catch (Exception ex) {
System.out.println("CustomFormatter:Caught exception trying to build log message.");
ex.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
}
}
return sb;
}
/**
* Returns caller location information in eclipse format eg (Filename.java:23) WARNING Generating caller location
* information is extremely slow. It's use should be avoided unless execution speed is not an issue.
*
* @param sb
*
* @return the eclipse format
*/
public StringBuffer getEclipseFormat(StringBuffer sb)
{
final boolean useCurrentThread = false;
// getStackTrace can be expensive
StackTraceElement[] stackTrace;
if (useCurrentThread) {
stackTrace = Thread.currentThread().getStackTrace();
} else {
// Its possible this is faster.
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302
stackTrace = new Throwable().getStackTrace();
}
StackTraceElement element = findCallingElement(stackTrace);
appendEclipseFormat(element, sb);
return sb;
}
public static StringBuffer appendEclipseFormat(final StackTraceElement element, final StringBuffer sb)
{
if (element == null || nullElement == element) {
sb.append("(?:?)");
} else {
sb.append('(');
String filename = element.getFileName();
if (filename == null || filename.isEmpty()) {
sb.append("?");
} else {
sb.append(filename);
}
sb.append(':');
int lineNumber = element.getLineNumber();
if (lineNumber <= 0) {
sb.append('?');
} else {
sb.append(lineNumber);
}
sb.append(')');
}
return sb;
}
public static StackTraceElement findCallingElement(StackTraceElement[] stackTrace)
{
StackTraceElement retval = nullElement;
int lastIdx = firstIndexNot(stackTrace, Logger.class.getName(), 7);
if (lastIdx >= 0 && lastIdx < stackTrace.length) {
retval = stackTrace[lastIdx];
}
return retval;
}
private static int firstIndexNot(StackTraceElement[] stackTrace,
String classname, int fromIndex)
{
int idx = -1;
if (classname != null) {
if (stackTrace != null && fromIndex >= 0 && stackTrace.length > fromIndex) {
for (int i = fromIndex; i < stackTrace.length; i++) {
if (!classname.equals(stackTrace[i].getClassName())) {
idx = i;
break;
}
}
}
}
return idx;
}
}
关于java - 如何在 java 日志记录属性文件中配置我自己的格式化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2710524/
这是真的: log(A) + log(B) = log(A * B) [0] 这也是真的吗? O(log(A)) + O(log(B)) = O(log(A * B)) [1] 据我了解 O(f
0 引言 我常以为 配置 INFO 日志级别时, 应用程序代码中日志器(logger) debug 级的日志代码,不会被执行(比如,实验1中的printTestLog函数)。但今天线上的问题,
日志 日志是构建工具的主要界面。如果日志太多,真正的警告和问题容易被隐藏。另一方面,如果出了错,你需要找出相关的信息。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
假设我们有速度关键的系统(例如统计/分析、套接字编程等),我们如何设计跟踪和日志。 更具体地说,日志和跟踪通常会降低性能(即使我们有关闭机制或冗长的扩展机制)。在这种情况下,是否有任何关于如何“放置”
我是一名优秀的程序员,十分优秀!