मुझे एक लाइन पर प्रदर्शित होने के लिए जावा लॉगिंग आउटपुट कैसे मिलता है?


124

फिलहाल एक डिफ़ॉल्ट प्रविष्टि कुछ इस तरह दिखती है:

Oct 12, 2008 9:45:18 AM myClassInfoHere
INFO: MyLogMessageHere

मुझे यह करने के लिए कैसे मिलता है?

Oct 12, 2008 9:45:18 AM myClassInfoHere - INFO: MyLogMessageHere

स्पष्टीकरण मैं java.util.log का उपयोग कर रहा हूं

जवाबों:


81

जावा 7 के रूप में, java.util.log.SimpleFormatter एक सिस्टम प्रॉपर्टी से इसका प्रारूप प्राप्त करने का समर्थन करता है, इसलिए JVM कमांड लाइन में इस तरह से कुछ जोड़ने से यह एक लाइन पर प्रिंट हो जाएगा:

-Djava.util.logging.SimpleFormatter.format='%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n'

वैकल्पिक रूप से, आप इसे अपने लिए भी जोड़ सकते हैं logger.properties:

java.util.logging.SimpleFormatter.format='%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n'

4
Java7 के रूप में सच है। Java6 डॉक्स में इसका कोई उल्लेख नहीं है।
जुबुनि

1
आईडिया में भी, दोहरे उद्धरण चिह्नों के साथ काम करता है। @jbruni यह Java6 में काम नहीं करता है।
जोशुआ डेविस

1
मेरे लिए ग्रहण में एकल उद्धरण के साथ काम करता है।
अमीर

1
% 1 $ tY-% 1 $ tm-% 1 $ td% 1 $ tH:% 1 $ tM:% 1 $ tS के बजाय आप% 1 $ tF% 1 $ tT लिख सकते हैं। इसे थोड़ा छोटा बनाता है। मुझे नहीं पता कि क्या यह और भी तेज़ है।
ब्रूनो एबरहार्ड

1
... या logging.properties@BrunoEberhard द्वारा सुझाव के आधार पर अनुकूलन के साथ और एक छोटा लकड़हारा नाम: java.util.logging.SimpleFormatter.format=%1$tF %1$tT %4$.1s %2$s %5$s%6$s%n
Kariem

73

1) -Djava.util.logging.SimpleFormatter.format

जावा 7 java.util.Formatterप्रारूप स्ट्रिंग सिंटैक्स के साथ एक संपत्ति का समर्थन करता है ।

-Djava.util.logging.SimpleFormatter.format=... 

देखें यहाँ

मेरी पसंदीदा है:

-Djava.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$-6s %2$s %5$s%6$s%n

जो उत्पादन की तरह बनाता है:

2014-09-02 16:44:57 SEVERE org.jboss.windup.util.ZipUtil unzip: Failed to load: foo.zip

2) इसे IDEs में डालना

आईडीई आमतौर पर आपको एक परियोजना के लिए सिस्टम गुण सेट करते हैं। उदाहरण के लिए, NetBeans में, जोड़ने के बजाय -D ... = ... कहीं, java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-...किसी भी उद्धरण के बिना - एक्शन डायलॉग में संपत्ति जोड़ें । आईडीई को पता लगाना चाहिए।

3) मावेन को यह कहना - अचूक

आपकी सुविधा के लिए, यह कैसे अचूक करने के लिए है:

        <!-- Surefire -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.17</version>
            <configuration>
                <systemPropertyVariables>
                    <!-- Set JUL Formatting -->
                    <java.util.logging.SimpleFormatter.format>%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$-6s %2$s %5$s%6$s%n</java.util.logging.SimpleFormatter.format>
                </systemPropertyVariables>
            </configuration>
        </plugin>

4) हाथ से बनाया गया

मेरे पास कुछ java.util.loggingसंबंधित कक्षाओं के साथ एक पुस्तकालय है । उनमें से, यह है SingleLineFormatterयहाँ डाउनलोड करने योग्य जार ।

public class SingleLineFormatter extends Formatter {

  Date dat = new Date();
  private final static String format = "{0,date} {0,time}";
  private MessageFormat formatter;
  private Object args[] = new Object[1];

  // Line separator string.  This is the value of the line.separator
  // property at the moment that the SimpleFormatter was created.
  //private String lineSeparator = (String) java.security.AccessController.doPrivileged(
  //        new sun.security.action.GetPropertyAction("line.separator"));
  private String lineSeparator = "\n";

  /**
   * Format the given LogRecord.
   * @param record the log record to be formatted.
   * @return a formatted log record
   */
  public synchronized String format(LogRecord record) {

    StringBuilder sb = new StringBuilder();

    // Minimize memory allocations here.
    dat.setTime(record.getMillis());    
    args[0] = dat;


    // Date and time 
    StringBuffer text = new StringBuffer();
    if (formatter == null) {
      formatter = new MessageFormat(format);
    }
    formatter.format(args, text, null);
    sb.append(text);
    sb.append(" ");


    // Class name 
    if (record.getSourceClassName() != null) {
      sb.append(record.getSourceClassName());
    } else {
      sb.append(record.getLoggerName());
    }

    // Method name 
    if (record.getSourceMethodName() != null) {
      sb.append(" ");
      sb.append(record.getSourceMethodName());
    }
    sb.append(" - "); // lineSeparator



    String message = formatMessage(record);

    // Level
    sb.append(record.getLevel().getLocalizedName());
    sb.append(": ");

    // Indent - the more serious, the more indented.
    //sb.append( String.format("% ""s") );
    int iOffset = (1000 - record.getLevel().intValue()) / 100;
    for( int i = 0; i < iOffset;  i++ ){
      sb.append(" ");
    }


    sb.append(message);
    sb.append(lineSeparator);
    if (record.getThrown() != null) {
      try {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        record.getThrown().printStackTrace(pw);
        pw.close();
        sb.append(sw.toString());
      } catch (Exception ex) {
      }
    }
    return sb.toString();
  }
}

दूसरे समाधान की तुलना में अच्छे स्मृति की खपत।
टिम विस्क्राफ्ट

मैंने यह कोशिश की - लेकिन यह मुझे XML में लॉग देता है - मैं क्या गलत कर रहा हूं - stackoverflow.com/questions/16030578/…
user93353

अगर यह आपके द्वारा अपेक्षित प्रारूप के बजाय XML को बदल देता है - इसका मतलब है कि आपकी गुण फ़ाइल में सेटिंग को आपका फ़ॉर्मेटर वर्ग नहीं मिला है, तो आप 2 चीजें कर सकते हैं: 1. सुनिश्चित करें कि आपकी कक्षा एक पैकेज में है और उस वर्ग के लिए फ़ॉर्मेटर संपत्ति सेट करें और पैकेज 2। सुनिश्चित करें कि आपकी कक्षा में "MyFormatter" जैसा एक अद्वितीय नाम है, अंतिम: सुनिश्चित करें कि सभी हैंडलर के पास वह फ़ॉर्मेटर है जो आप चाहते थे (java.util.log.ConsoleHandler.formatter = my.package.MandFormatter और भी: java.util .log.FileHandler.formatter = my.package.MyFormatter)
Shaybc

साझा करने के लिए धन्यवाद। मैंने एक और प्रश्न के उत्तर में लिखा एक फॉर्मैटर साझा किया । इसने मेरे लिए ठीक प्रदर्शन किया। मुझे लगता है कि अन्य डेवलपर्स कोड को छोटा और तेज बनाने के लिए आते हैं।
रयान

1
@ ondra-Žižka इसके लायक क्या है मैंने अभी आपको अपने Google कोड रेपो पर एक पैच भेजा है।
रयान

61

Tervor के समान, लेकिन मुझे रनटाइम पर संपत्ति बदलना पसंद है।

ध्यान दें कि पहले SimpleFormatter बनने से पहले इसे सेट करना होगा - जैसा कि टिप्पणियों में लिखा गया था।

    System.setProperty("java.util.logging.SimpleFormatter.format", 
            "%1$tF %1$tT %4$s %2$s %5$s%6$s%n");

6
ध्यान दें कि इसे पहले SimpleFormatter बनाने से पहले सेट करने की आवश्यकता है - उदाहरण के लिए वैश्विक लकड़हारा हैंडलर प्राप्त करने से पहले।
विल्पी

5
JVM में किसी अन्य स्टार्टअप पैरामीटर को जोड़े बिना अपने लॉग को एक पंक्ति में लिखने के लिए मजबूर करने का यह सबसे तेज़ तरीका है। लेकिन इससे पहले कि आप अपने कोड में 'नई SimpleFormatter ()' को कॉल करने से पहले यह सुनिश्चित कर लें कि आप इस संपत्ति को सेट करते हैं।
साल्वाडोर वालेंसिया

36

जैसे ओबेद्याह स्टैन ने कहा, अपनी खुद की formatविधि बनाना आवश्यक है । लेकिन मैं कुछ चीजें बदलूंगा:

  • से सीधे उप-वर्ग बनाएं Formatter, नहीं SimpleFormatterSimpleFormatterअब और जोड़ने के लिए कुछ भी नहीं है।

  • एक नई Dateवस्तु बनाने के साथ सावधान रहें ! की तारीख का प्रतिनिधित्व करने के लिए आपको सुनिश्चित करना चाहिए LogRecordDateडिफॉल्ट कंस्ट्रक्टर के साथ एक नया निर्माण करते समय, यह उन Formatterप्रक्रियाओं को दिनांक और समय का प्रतिनिधित्व करेगा LogRecord, जो उस तारीख को नहीं LogRecordबनाया गया था।

निम्न वर्ग को फॉर्मेटर के रूप में इस्तेमाल किया जा सकता है Handler, जिसे बदले में जोड़ा जा सकता है Logger। ध्यान दें कि यह उपलब्ध सभी वर्ग और पद्धति की जानकारी को अनदेखा करता है LogRecord

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public final class LogFormatter extends Formatter {

    private static final String LINE_SEPARATOR = System.getProperty("line.separator");

    @Override
    public String format(LogRecord record) {
        StringBuilder sb = new StringBuilder();

        sb.append(new Date(record.getMillis()))
            .append(" ")
            .append(record.getLevel().getLocalizedName())
            .append(": ")
            .append(formatMessage(record))
            .append(LINE_SEPARATOR);

        if (record.getThrown() != null) {
            try {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                record.getThrown().printStackTrace(pw);
                pw.close();
                sb.append(sw.toString());
            } catch (Exception ex) {
                // ignore
            }
        }

        return sb.toString();
    }
}

मैंने यह कोशिश की - लेकिन यह मुझे XML में लॉग देता है - मैं क्या गलत कर रहा हूं - stackoverflow.com/questions/16030578/…
user93353

अगर यह आपके द्वारा अपेक्षित प्रारूप के बजाय XML को बदल देता है - इसका मतलब है कि आपकी गुण फ़ाइल में सेटिंग को आपका फ़ॉर्मेटर वर्ग नहीं मिला है, तो आप 2 चीजें कर सकते हैं: 1. सुनिश्चित करें कि आपकी कक्षा एक पैकेज में है और उस वर्ग के लिए फ़ॉर्मेटर संपत्ति सेट करें और पैकेज 2। सुनिश्चित करें कि आपकी कक्षा में "MyFormatter" जैसा एक अद्वितीय नाम है, अंतिम: सुनिश्चित करें कि सभी हैंडलर के पास वह फ़ॉर्मेटर है जो आप चाहते थे (java.util.log.ConsoleHandler.formatter = my.package.MandFormatter और भी: java.util .log.FileHandler.formatter = my.package.MyFormatter)
शायब

10

यह मैं उपयोग कर रहा हूं।

public class VerySimpleFormatter extends Formatter {

    private static final String PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";

    @Override
    public String format(final LogRecord record) {
        return String.format(
                "%1$s %2$-7s %3$s\n",
                new SimpleDateFormat(PATTERN).format(
                        new Date(record.getMillis())),
                record.getLevel().getName(), formatMessage(record));
    }
}

आपको कुछ ऐसा मिलेगा ...

2016-08-19T17:43:14.295+09:00 INFO    Hey~
2016-08-19T17:43:16.068+09:00 SEVERE  Seriously?
2016-08-19T17:43:16.068+09:00 WARNING I'm warning you!!!

हम इस फॉर्मेटर आउटपुट अपवाद की जानकारी कैसे प्राप्त कर सकते हैं, जैसे कि इसका स्टैकट्रेस?
झगड़ा

1
@ Fagemo मुझे लगता है कि आप इस तरह से स्टारट्रेस प्रिंट कर सकते हैं। ofNullable(record.getThrown()).ifPresent(v -> v.printStackTrace());स्वरूपित संदेश लौटने से पहले।
जिन क्वॉन

7

ग्रहण का विन्यास

प्रति स्क्रीनशॉट, एक्लिप्स में "फिर रन" के रूप में "रन कॉन्फ़िगरेशन ..." का चयन करें और ट्रेवर रॉबिन्सन के उत्तर को दोहरे उद्धरण चिह्नों के बजाय जोड़ दें। यदि आपको डबल कोट्स याद हैं तो आपको "मुख्य वर्ग की त्रुटियां नहीं मिलेंगी या लोड नहीं होंगी"।


2
पिछले उत्तर के अनुसार, यह जावा 7 में काम करता है। जावा 6 में यह सुविधा नहीं है।
जोशुआ डेविस

5

मैंने एक तरीका निकाला है जो काम करता है। आप SimpleFormatter को उप-वर्ग कर सकते हैं और प्रारूप विधि को ओवरराइड कर सकते हैं

    public String format(LogRecord record) {
        return new java.util.Date() + " " + record.getLevel() + " " + record.getMessage() + "\r\n";
    }

इस एपीआई पर थोड़ा सा आश्चर्य मुझे लगा होगा कि बॉक्स के बाहर अधिक कार्यक्षमता / लचीलापन प्रदान किया गया होगा


के formatMessage(record)बजाय किसी का उपयोग करना चाहिए record.getMessage()। स्थान धारक परिवर्तित नहीं होंगे।
जिन क्वाँ

-2

यह लॉगिंग आपके एप्लिकेशन के लिए विशिष्ट है न कि सामान्य जावा सुविधा के लिए। आप क्या एप्लिकेशन चला रहे हैं?

यह हो सकता है कि यह एक विशिष्ट लॉगिंग लाइब्रेरी से आ रहा है जिसे आप अपने कोड के भीतर उपयोग कर रहे हैं। यदि हां, तो कृपया उन विवरणों को पोस्ट करें जिनका आप उपयोग कर रहे हैं।


3
यह कुछ यादृच्छिक लकड़हारा आवेदन नहीं है। यह जावा का अपना हैjava.util.logging.Logger
एंड्रे सी। एंडर्सन

-2

यदि आप tomcat add का उपयोग करके किसी वेब एप्लिकेशन में लॉग इन करते हैं:

-Djava.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter

VM तर्कों पर


-3

यदि आप java.util.log का उपयोग कर रहे हैं, तो एक कॉन्फ़िगरेशन फ़ाइल है जो सामग्री लॉग करने के लिए ऐसा कर रही है (जब तक कि आप प्रोग्राम कॉन्फ़िगरेशन का उपयोग नहीं कर रहे हैं)। तो, आपके विकल्प
1) रन पोस्ट -प्रोसेसर है जो लाइन ब्रेक
2 को हटाता है ) लॉग कॉन्फ़िगरेशन को बदलें और इससे लाइन ब्रेक को हटा दें। अपने एप्लिकेशन (सर्वर) को पुनरारंभ करें और आपको अच्छा होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.