Использование Log4J только из кода Java [duplicate]

В следующем примере, который я написал, показано, как

  • обрабатывать асинхронные HTTP-вызовы;
  • Подождать ответа от каждого вызова API;
  • Использовать шаблон promise ;
  • Используйте шаблон Promise.All для объединения нескольких HTTP-вызовов;

Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.

Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist для заданного набора строк запроса:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

Для каждого элемента новый Promise запустит блок - ExecutionBlock, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user и выполняет новый HTTP-вызов в ExecutionProfileBlock асинхронно.

Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all.

NOTE Recent Spotify search API-интерфейсам потребуется указать токен доступа в заголовках запроса:

-H "Authorization: Bearer {your access token}" 

Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:

var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
    log: function(s) {
        document.getElementById("console").innerHTML += s + "
" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // State changes request.onreadystatechange = function() { if (request.readyState === 4) { // Done if (request.status === 200) { // Complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { var url = "https://api.spotify.com/v1/" url += item; console.log( url ) SimpleRequest.call(url, function(result) { if (result) { var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) { return item.owner.href; }) resolve(profileUrls); } else { reject(new Error("call error")); } }) } arr = [ "search?type=playlist&q=%22doom%20metal%22", "search?type=playlist&q=Adele" ] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // Aggregated results console.log("All profiles received " + results.length); //console.log(JSON.stringify(results[0], null, 2)); ///// promiseall again var ExecutionProfileBlock = function(item, index, resolve, reject) { SimpleRequest.call(item, function(result) { if (result) { var obj = JSON.parse(result); resolve({ name: obj.display_name, followers: obj.followers.total, url: obj.href }); } //result }) } //ExecutionProfileBlock promiseAll(results[0], function(item, index, resolve, reject) { //console.log("Making request [" + index + "] " + item) ExecutionProfileBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results, null, 2)); } , function(error) { // Error console.log(error); }) ///// }, function(error) { // Error console.log(error); });

Я подробно рассмотрел это решение здесь .

169
задан ROMANIA_engineer 22 October 2014 в 11:29
поделиться

3 ответа

Вы можете добавить / удалить Appender программно в Log4j:

  ConsoleAppender console = new ConsoleAppender(); //create appender
  //configure the appender
  String PATTERN = "%d [%p|%c|%C{1}] %m%n";
  console.setLayout(new PatternLayout(PATTERN)); 
  console.setThreshold(Level.FATAL);
  console.activateOptions();
  //add appender to any Logger (here is root)
  Logger.getRootLogger().addAppender(console);

  FileAppender fa = new FileAppender();
  fa.setName("FileLogger");
  fa.setFile("mylog.log");
  fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
  fa.setThreshold(Level.DEBUG);
  fa.setAppend(true);
  fa.activateOptions();

  //add appender to any Logger (here is root)
  Logger.getRootLogger().addAppender(fa);
  //repeat with all other desired appenders

Я бы предложил вам поместить его в init () где-нибудь, где вы уверены, что это будет выполнено раньше всего , Затем вы можете удалить все существующие приложения в корневом журнале с помощью

 Logger.getRootLogger().getLoggerRepository().resetConfiguration();

и начать с добавления своего собственного. Для этого вам нужно log4j в курсе classpath.

Примечание. Вы можете использовать любой Logger.getLogger(...), который вам нравится добавлять. Я просто взял корневой журнал, потому что он находится в нижней части всех вещей и будет обрабатывать все, что передается через другие приложения в других категориях (если не настроено иначе, установив флаг аддитивности).

Если вам нужно знать, как работает журнал, и как определяется, где записываются журналы , прочитайте это руководство для получения дополнительной информации об этом. Короче:

  Logger fizz = LoggerFactory.getLogger("com.fizz")

предоставит вам регистратор для категории «com.fizz». В приведенном выше примере это означает, что все, что было зарегистрировано с ним, будут переданы в консоль и файл appender в корневом журнале. Если вы добавите приложение в Logger.getLogger («com.fizz»). AddAppender (newAppender), то регистрация из fizz будет обрабатываться всеми добавками из корневого регистратора и newAppender. Вы не создаете Loggers с конфигурацией, вы просто предоставляете обработчики для всех возможных категорий в вашей системе.

253
ответ дан Aamir 26 August 2018 в 02:02
поделиться

Похоже, вы пытаетесь использовать log4j с «обоих концов» (конечный потребитель и конец конфигурации).

Если вы хотите скопировать код slf4j api, но заранее определить заранее ( и программно) конфигурация log4j Loggers, возвращаемая классом, вам абсолютно необходимо иметь какую-то привязку регистрации, которая использует ленивую конструкцию.

public class YourLoggingWrapper {
    private static boolean loggingIsInitialized = false;

    public YourLoggingWrapper() {
        // ...blah
    }

    public static void debug(String debugMsg) {
        log(LogLevel.Debug, debugMsg);
    }

    // Same for all other log levels your want to handle.
    // You mentioned TRACE and ERROR.

    private static void log(LogLevel level, String logMsg) {
        if(!loggingIsInitialized)
            initLogging();

        org.slf4j.Logger slf4jLogger = org.slf4j.LoggerFactory.getLogger("DebugLogger");

        switch(level) {
        case: Debug:
            logger.debug(logMsg);
            break;
        default:
            // whatever
        }
    }

    // log4j logging is lazily constructed; it gets initialized
    // the first time the invoking app calls a log method
    private static void initLogging() {
        loggingIsInitialized = true;

        org.apache.log4j.Logger debugLogger = org.apache.log4j.LoggerFactory.getLogger("DebugLogger");

        // Now all the same configuration code that @oers suggested applies...
        // configure the logger, configure and add its appenders, etc.
        debugLogger.addAppender(someConfiguredFileAppender);
    }

При таком подходе вы не нужно беспокоиться о том, где / когда ваш log4j loggers настроен. В первый раз, когда classpath просит их, они лениво построены, переданы обратно и доступны через slf4j. Надеюсь, это помогло!

42
ответ дан Christophe Roussy 26 August 2018 в 02:02
поделиться

В том случае, если вы определили приложение в свойствах log4j и хотите его программно обновить, задайте имя в свойствах log4j и получите его по имени.

Вот пример записи log4j.properties :

log4j.appender.stdout.Name=console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=INFO

Чтобы обновить его, выполните следующие действия:

((ConsoleAppender) Logger.getRootLogger().getAppender("console")).setThreshold(Level.DEBUG);
1
ответ дан Kyle Shrader 26 August 2018 в 02:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: