java - loggerfactory - slf4j example
¿Hay una función general de sustitución de cadenas similar a sl4fj? (5)
Con sl4fj si quiero construir un mensaje de cadena hay un buen enfoque que hace uso de sustituciones. Por ejemplo, podría ser algo así como:
logger.info("Action {} occured on object {}.", objectA.getAction(), objectB);
Si hay más de unas pocas sustituciones requeridas, entonces es algo así como:
logger.info("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Mi pregunta es: ¿existe una forma genérica para mí de crear una cadena (y no solo un mensaje de registro slf4j)? Algo como:
String str = someMethod("Action {} occured on object {}.", objectA.getAction(), objectB);
o
String str = someMethod("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Si está en la biblioteca estándar de Java, ¿qué sería ese "algúnMétodo"?
Elijo envolver el Log4j2 ParameterizedMessage que fue escrito originalmente para Lilith por Joern Huxhorn:
public static String format(final String messagePattern, Object... arguments) {
return ParameterizedMessage.format(messagePattern, arguments);
}
Se centra en el formato del mensaje, a diferencia de SLF4J MessageFormatter que contiene el procesamiento innecesario de Throwable.
Ver el Javadoc:
Maneja mensajes que consisten en una cadena de formato que contiene ''{}'' para representar cada token reemplazable y los parámetros.
Puede utilizar String.format o MessageFormat.format
P.ej,
MessageFormat.format("A sample value {1} with a sample string {0}",
new Object[] {"first", 1});
o simplemente
MessageFormat.format("A sample value {1} with a sample string {0}", "first", 1);
Si está buscando una solución donde pueda reemplazar un conjunto de variables en una cadena con valores, puede usar StrSubstitutor .
Map<String, String> valuesMap = new HashMap<>();
valuesMap.put("animal", "quick brown fox");
valuesMap.put("target", "lazy dog");
String templateString = "The ${animal} jumped over the ${target}.";
StrSubstitutor sub = new StrSubstitutor(valuesMap);
String resolvedString = sub.replace(templateString);
Sigue un patrón generalmente aceptado en el que uno puede pasar un mapa con variables a valores junto con el String no resuelto y devuelve un String resuelto.
Sugeriría usar org.slf4j.helpers.MessageFormatter . Con la ayuda de este, uno puede crear un método utillity que use el mismo estilo de formato exacto que slf4j:
// utillity method to format like slf4j
public static String format(String msg, Object... objs) {
return MessageFormatter.arrayFormat(msg, objs).getMessage();
}
// example usage
public static void main(String[] args) {
String msg = format("This msg is {} like slf{}j would do. {}", "formatted", 4,
new Exception("Not substituted into the message"));
// prints "This msg is formatted like slf4j would do. {}"
System.out.println(msg);
}
Nota : Si el último objeto de la matriz es una excepción, no se sustituirá en el mensaje, al igual que con un registrador slf4j. La excepción sería accesible a través de MessageFormatter.arrayFormat(msg, objs).getThrowable()
.
String str = String.format("Action %s occured on object %s.",
objectA.getAction(), objectB);
O
String str = String.format("Action %s occured on object %s with outcome %s.",
new Object[]{objectA.getAction(), objectB, outcome});
También puede usar posiciones numéricas, por ejemplo para cambiar los parámetros:
String str = String.format("Action %2$s occured on object %1$s.",
objectA.getAction(), objectB);