簡體   English   中英

在 Java 中創建用於記錄或異常的消息的最佳實踐

[英]Best Practices to create Message for Logging or Exception in Java

我在 Java 6 中找到了這個代碼。

String mensajeExcluido = ArqSpringContext.getPropiedad("MENSAJE.EXCLUIDO");
LOG.warn("ERROR: Servicio: " + mensajeExcluido + ":" + someDTO.getProperty() +
        ",\tsomeValue:" + someDTO.getValue() + "'.");
throw new Exception(mensajeExcluido);

這段代碼

String mensajeExcluido = ArqSpringContext.getPropiedad("REGLA.MENSAJE");
String mensajeWarn = "ALERTA: Otro Servicio: " + mensajeExcluido + ":" +
        someDTO.getProperty() + ",\tsomeValue:" + someDTO.getValue() + "'.";
LOG.warn(mensajeWarn);

boolean exclusionVisible = Boolean.valueOf(ArqSpringContext.getPropiedad("EXCLUSION.VISIBLE"));
if (exclusionVisible) {
    mensajeWarn = "<br></br>" + mensajeWarn;
} else {
    mensajeWarn = "";
}
throw new Exception(mensajeExcluido + mensajeWarn);

這個代碼

LOG.warn("No se pudo validar Client Service. Code: " +
        someDTO.getStatusCode() + ".");
return "No se pudo validar Client Service. Code: " +
        someDTO.getStatusCode() + ".";

為了遵循最佳實踐...

哪些建議適用?

他們會對代碼進行哪些更改?

文本應該如何處理?

首先,在檢查是否應該打印日志語句之前盡量避免消息創建處理(即:在檢查日志級別之前不要連接消息字符串。

// Better this
if (LOG.isDebugEnabled())
    LOG.debug("This is a message with " + variable + " inside");

// Than this
final String message = "This is a message with " + variable + " inside";
if (LOG.isDebugEnabled())
    LOG.debug(message);

大多數 Java 日志框架允許提前檢查是否要根據給定設置打印日志語句。

如果您想減輕為每個日志語句編寫檢查的負擔,您可以利用 Java 8 lambda 並編寫如下實用程序:


import java.util.function.Supplier;
import java.util.logging.Logger;

import static java.util.logging.Level.FINE;

class MyLogger {

    public static MyLogger of(final Class<?> loggerClass) {
        return new MyLogger(loggerClass);
    }

    private final Logger logger;

    private MyLogger(final Class<?> loggerClass) {
        logger = Logger.getLogger(loggerClass.getName());
    }

    // Supplier will be evaluated AFTER checking if log statement must be executed
    public void fine(final Supplier<?> message) {
        if (logger.isLoggable(FINE))
            logger.log(FINE, message.get().toString());
    }
}

static final LOG = MyLogger.of(String.class);

public void example() {
    LOG.fine(() -> "This is a message with a system property: " + System.getProperty("property"));
}

最后,您可以利用 Java 字符串格式化來使用String.format格式化日志消息。 IE:

final String message = String.format("Print %s string and %d digit", "str", 42);

應用於您提供的示例的那些良好做法將是:

/*
 * Using java.util.logging in JDK8+
 */

import java.util.logging.Level;
import java.util.logging.Logger;

import static java.lang.String.format;

class Dto {
    String getProperty() { return "property"; }
    String getValue() { return "property"; }
    String getStatusCode() { return "statusCode"; }
}

final Logger LOG = Logger.getGlobal();
final Dto someDTO = new Dto();

void example1() throws Exception {
    String mensajeExcluido = System.getProperty("MENSAJE.EXCLUIDO");

    // Check if log will be printed before composing the log message
    if (LOG.isLoggable(Level.WARNING)) {
        // Using String.format usually is clearer and gives you more formatting options
        final String messageFormat = "ERROR: Servicio: %s:%s,\tsomeValue:%s'.";
        LOG.warning(format(messageFormat, mensajeExcluido, someDTO.getProperty(), someDTO.getValue()));
    }

    // Or using lambdas
    LOG.warning(() -> {
        final String message = "ERROR: Servicio: %s:%s,\tsomeValue:%s'.";
        return format(message, mensajeExcluido, someDTO.getProperty(), someDTO.getValue());
    });

    throw new Exception(mensajeExcluido);
}

void example2() throws Exception {
    String mensajeExcluido = System.getProperty("REGLA.MENSAJE");
    String mensajeWarn = format(
        // The concatenated message is probably missing a single quote at 'someValue'
        "ALERTA: Otro Servicio: %s:%s,\tsomeValue:%s'.",
        mensajeExcluido,
        someDTO.getProperty(),
        someDTO.getValue()
    );

    LOG.warning(mensajeWarn);

    boolean exclusionVisible = Boolean.parseBoolean(System.getProperty("EXCLUSION.VISIBLE"));
    String exceptionMessage = exclusionVisible ?
            mensajeExcluido + "<br></br>" + mensajeWarn : mensajeExcluido;

    throw new Exception(exceptionMessage);
}

String example3() {
    // You can compose the message only once and use it for the log and the result
    String message =
        format("No se pudo validar Client Service. Code: %s.", someDTO.getStatusCode());
    LOG.warning(message);
    return message;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM