Beh, ho pensato a questa domanda e questo è ciò che ottengo:
Restrizioni
Cita il proprietario della domanda:
- Per implementare il mio RestTemplate è troppo pesante
But I saw that RestTemplate is pretty expensive object to create, when about 70% of the creation time, is creating the MessageConverters.
-
RestTemplate non è thread-safe dopo la costruzione. Ma non è dopo la costruzione . Vedi altro Il thread di RestTemplate è sicuro?
Conceptually, it is very similar to the JdbcTemplate, JmsTemplate, and the various other templates found in the Spring Framework and other portfolio projects. This means, for instance, that the RestTemplate is thread-safe once constructed
Questa ultima funzione suggerisce di non modificare un RestTemplate dopo la sua costruzione. Quindi non aggiungerei né alcun nuovo Interceptor, né rimuoverlo
-
Ci mancano molti dettagli sul sistema e sui suoi requisiti, limiti, ecc ...
-
Non sappiamo a cosa servono questi file. Quindi compromette l'adeguatezza della soluzione che propongo.
Che cosa abbiamo?
Se ho ragione, abbiamo configurato Appache Log4J . ( @Nati mi ha detto per chat ).
Quindi ho deciso di usare Log4j come strumento di registrazione. Tuttavia, consulta la sezione Svantaggi . ( spero che qualcun altro a leggere questa risposta possa dissipare i miei dubbi )
Perché Log4j invece della mia gestione dei file? Perché volevo delegare a Log4j le seguenti funzionalità: accesso ai file , utilizzo dei pattern , utilizzo dei filtri (facoltativo) , utilizzo dei livelli , ...
Soluzione
LoggerHelper
Ho implementato un helper per rendere la soluzione portatile attraverso qualsiasi livello con il minor accoppiamento possibile.
package org.myworkouts.helper;
import java.io.File;
import java.io.IOException;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
public class LoggerHelper {
// Helper's own logger
private static final Logger LOGGER = LogManager
.getLogger(LoggerHelper.class);
private static final String DEFAULT_LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n";
private static final String LOGGER_PREFIX = "logger";
private static final String APPENDER_PREFIX = "appender";
private static LoggerHelper instance = null;
// Singleton
private LoggerHelper() {
super();
}
public static LoggerHelper getInstance() {
if (instance == null) {
instance = new LoggerHelper();
}
return instance;
}
/**
* Get the logger by its name or create if never was instanciated previously
*
* @throws IOException
*/
public Logger getCustomFileLogger(String filePath) throws IOException {
String loggerName = resolveLoggerName(filePath);
Logger logger = LogManager.exists(loggerName);
if (logger == null) {
LOGGER.info("Creating new Logger: ".concat(loggerName));
logger = LogManager.getLogger(loggerName);
}
setLevel(logger, Level.INFO).addFileAppender(logger, filePath);
return logger;
}
private LoggerHelper addFileAppender(Logger logger, String filePath)
throws IOException {
if (logger != null) {
String appenderName = resolveAppenderName(filePath);
if (logger.getAppender(appenderName) == null) {
logger.addAppender(new FileAppender(new PatternLayout(
DEFAULT_LOG_PATTERN), filePath, Boolean.TRUE));
}
}
return this;
}
private LoggerHelper setLevel(Logger logger, Level level) {
if (logger != null) {
logger.setLevel(level);
}
return this;
}
/* Optionl. Generate a custom name for a new Appender */
private String resolveAppenderName(String filePath) {
return APPENDER_PREFIX.concat(File.pathSeparator).concat(
getNameWithoutExtension(filePath));
}
/* Optionl. Generate a custom name for a new Logger */
private String resolveLoggerName(String filePath) {
return LOGGER_PREFIX.concat(File.pathSeparator).concat(
getNameWithoutExtension(filePath));
}
//Took from com.google.common.io.Files
//I had it in my workspace but I didn't want to use it at this
//class
private String getNameWithoutExtension(String filePath) {
String fileName = new File(filePath).getName();
int dotIndex = fileName.lastIndexOf('.');
return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
}
}
Attuazione
Allegare la soluzione al codice proprietario
protected MyResponse<MyInterface> getInterfaces(RestTemplate restClient, RestParams inputParams, String cookie, File outputFile) {
Request devInterfacesRequest = getRequest(RequestType.INTERFACES, inputParams, cookie);
MyResponse<MyInterface> response = restClient.postForObject(inputParams.getUrl(), devInterfacesRequest , new ParameterizedTypeReference<MyResponse<MyInterface>>(){});
try{
Logger customLogger = LoggerHelper.getInstance().getCustomFileLogger(outputFile.getPath());
//... we can also to parse it to Json, XML, whatever...
customLogger.info(response.toString());
}catch(IOException ex){
//... what do we have to do if logger could not be instanciated?
}
return response;
}
Nota : L'implementazione potrebbe anche essere spostata in getInterfaces
chiamante che ha (suppongo) un for
bucle e decide anche il outputFile
. Quindi getCustomFileLogger(...)
verrebbe invocato una sola volta.
test
public class LoggerHelperTest {
public static final Logger LOGGER = LogManager.getLogger(LoggerHelperTest.class);
@Test
public void getCustomLoggerTest() throws IOException{
Logger customLogger = LoggerHelper.getInstance().getCustomFileLogger("file.txt");
Assert.assertNotNull("CustomLogger should not be null",customLogger);
Assert.assertEquals("CustomLogger's level should be INFO by default",Level.INFO, customLogger.getLevel());
Assert.assertTrue("CustomLogger's name should contain file's name on its name",customLogger.getName().contains("file"));
customLogger.info("Trace 1");
customLogger.info("Trace 2");
customLogger.info("Trace 3");
}
}
file.txt
L'output che ho ottenuto
2016-05-03 13:38:56 INFO logger:file:47 - Trace 1
2016-05-03 13:38:56 INFO logger:file:48 - Trace 2
2016-05-03 13:38:56 INFO logger:file:49 - Trace 3
Dubbi
Questo è un suggerimento. È aperto a suggerimenti o miglioramenti. Ho anche i miei dubbi sulla mia soluzione. ( Non ho sottolineato la soluzione ):
- È File outputFile bloccato (aperto) da qualsiasi altro processo? Quindi verrà lanciata IOException.
- Home page qualsiasi diverso outputFile sono? 10,100,1000? Possiamo tenere un sacco di Logger in Log4j?
- Questi outputFile verranno spostati in runtime? Se qualcuno viene spostato / eliminato / sostituito log4j, non sarà in grado di continuare ad accedere.
- Prenderemo IOException invece di lasciarlo andare ?. Delega a LoggerHelper l'utente per decidere cosa fare ...
Ho usato Log4j perché ho avuto in mente che il requisito è di tenere separati i logger che stampano tutti sul proprio file. Ma mi aspetto che contengano solo tracce di registro ( per ulteriori recensioni o debug ).
Tuttavia, se il contenuto del file è importante, se il contenuto è importante per noi, la soluzione non è adatta.
Se il contenuto conta e non voglio implementare una gestione dei file , penserei di archiviare questi log in noSQL db's (mongoDB o qualsiasi altro più adatto per la nostra piattaforma) che è anche in grado di supportare un volume elevato di dati. I dati possono essere ottenuti in seguito con richieste appropriate