আমি কীভাবে একটি এক লাইনে জাভা লগিং আউটপুট পেতে পারি?


124

এই মুহুর্তে একটি ডিফল্ট এন্ট্রি এরকম কিছু দেখায়:

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

এটি করার জন্য আমি এটি কীভাবে পেতে পারি?

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

স্পষ্টকরণ আমি java.util.logging ব্যবহার করছি

উত্তর:


81

জাভা 7-এর হিসাবে, java.util.logging.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
জাভা 7-তে সত্য। জাভা 6 ডক্সে এর কোনও উল্লেখ নেই।
jbruni

1
আইডিইএতেও ডাবল উদ্ধৃতি দিয়ে কাজ করে। @jbruni এটি জাভা in তে কাজ করে না।
জোশুয়া ডেভিস

1
আমার জন্য এক্সিলিপসে একক উক্তি নিয়ে কাজ করে।
সমৃদ্ধ

1
% 1 $ tY-% 1 $ tm-% 1 $ td% 1 $ tH:% 1 $ tM:% 1 $ tS এর পরিবর্তে আপনি% 1 $ tF% 1 $ tT লিখতে পারেন। এটিকে খানিকটা খাটো করে তোলে। আমি জানি না এটি আরও দ্রুত কিনা।
ব্রুনো এবারহার্ড

1
... বা ইন logging.properties, @ ব্রুনো এবারহার্ড এবং একটি সংক্ষিপ্ত লগার নামের পরামর্শের ভিত্তিতে অভিযোজন সহ: java.util.logging.SimpleFormatter.format=%1$tF %1$tT %4$.1s %2$s %5$s%6$s%n
ক্যারিম

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) এটি আইডিইগুলিতে লাগানো

আইডিইগুলি সাধারণত আপনাকে কোনও প্রকল্পের জন্য সিস্টেমের বৈশিষ্ট্য সেট করতে দেয়। যেমন নেটবিনে, ডি-ডি যোগ করার পরিবর্তে ... = ... কোথাও, অ্যাকশন কথোপকথনে সম্পত্তি যুক্ত করুন 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

যদি এটি আপনার প্রত্যাশিত বিন্যাসের পরিবর্তে এক্সএমএল হয়ে যায় - এর অর্থ হল আপনার সম্পত্তি ফাইলের সেটিংটি আপনার ফর্ম্যাটার শ্রেণিটি খুঁজে পায়নি, আপনি 2 টি কাজ করতে পারেন: ১. নিশ্চিত করুন যে আপনার ক্লাসটি কোনও প্যাকেজে রয়েছে এবং সেই শ্রেণিতে বিন্যাসের সম্পত্তি সেট করুন make এবং প্যাকেজ ২. নিশ্চিত করুন যে আপনার ক্লাসটির "মাইফর্ম্যাটটার" এর মতো একটি অনন্য নাম রয়েছে, শেষ: নিশ্চিত করুন যে সমস্ত হ্যান্ডলারের আপনার পছন্দসই ফর্ম্যাটর রয়েছে (java.util.logging.ConsoleHandler.formatter = my.package.MyFormatter এবং এছাড়াও: java.util .logging.FileHandler.formatter = my.package.MyFormatter)
Shaybc

ভাগ করে নেওয়ার জন্য ধন্যবাদ. আমি অন্য একটি প্রশ্নের জবাবে আমি লিখেছি এমন একটি ফর্ম্যাটর ভাগ করেছি । এটি আমার জন্য ঠিক আছে। কোডটি আরও ছোট এবং দ্রুত করার জন্য অন্যান্য বিকাশকারীরা যে কৌশলগুলি নিয়ে এসেছেন তা আমি দেখতে চাই।
রায়ান

1
@ অনড্রা-žižka এর মূল্যের জন্য আমি আপনাকে আপনার গুগল কোড রেপোতে একটি প্যাচ পাঠিয়েছি।
রায়ান

61

ট্র্যাভরের মতো, তবে আমি রানটাইমে সম্পত্তি পরিবর্তন করতে চাই।

মনে রাখবেন যে প্রথম সিম্পাল ফর্ম্যাটটার তৈরি হওয়ার আগে এটি সেট করা দরকার - যা মন্তব্যগুলিতে লেখা হয়েছিল।

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

6
মনে রাখবেন যে প্রথম সিম্পাল ফর্ম্যাটটার তৈরি হওয়ার আগে এটি সেট করা দরকার - উদাহরণস্বরূপ গ্লোবাল লগারের হ্যান্ডলারগুলি পাওয়ার আগে।
শেপি

5
আপনার লগগুলিকে জেভিএম-তে অন্য কোনও প্রারম্ভিক পরামিতি যুক্ত না করে একক লাইনে লিখতে বাধ্য করার এই দ্রুততম উপায়। তবে আপনার কোডটিতে 'নতুন সরলফর্ম্যাটর ()' এ কল করার আগে আপনি এই সম্পত্তিটি সেট করেছেন তা নিশ্চিত করুন।
সালভাদোর ভ্যালেন্সিয়া

36

ওবেদিয়াহ স্টেন যেমন বলেছেন, আপনার নিজের formatপদ্ধতি তৈরি করা প্রয়োজন । তবে আমি কয়েকটি জিনিস পরিবর্তন করব:

  • সরাসরি Formatterনয়, থেকে প্রাপ্ত একটি সাবক্লাস তৈরি করুন SimpleFormatter। এর SimpleFormatterআর যোগ করার কিছু নেই।

  • একটি নতুন 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

যদি এটি আপনার প্রত্যাশিত বিন্যাসের পরিবর্তে এক্সএমএল হয়ে যায় - এর অর্থ হল আপনার সম্পত্তি ফাইলের সেটিংটি আপনার ফর্ম্যাটার শ্রেণিটি খুঁজে পায়নি, আপনি 2 টি কাজ করতে পারেন: ১. নিশ্চিত করুন যে আপনার ক্লাসটি কোনও প্যাকেজে রয়েছে এবং সেই শ্রেণিতে বিন্যাসের সম্পত্তি সেট করুন make এবং প্যাকেজ ২. নিশ্চিত করুন যে আপনার ক্লাসটির "মাইফর্ম্যাটটার" এর মতো একটি অনন্য নাম রয়েছে, শেষ: নিশ্চিত করুন যে সমস্ত হ্যান্ডলারের আপনার পছন্দসই ফর্ম্যাটর রয়েছে (java.util.logging.ConsoleHandler.formatter = my.package.MyFormatter এবং এছাড়াও: java.util .logging.FileHandler.formatter = my.package.MyFormatter)
Shaybc

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
@ ফেজেমো আমি মনে করি আপনি স্টারট্রেসটি এটি প্রিন্ট করতে পারেন। ofNullable(record.getThrown()).ifPresent(v -> v.printStackTrace());ফর্ম্যাট বার্তা ফিরে আসার ঠিক আগে।
জিন কোওন

7

Eclipse config

প্রতি স্ক্রিনশট অনুসারে, অ্যালিপসে "হিসাবে রান করুন" তারপরে "কনফিগারেশনগুলি চালান ..." নির্বাচন করুন এবং ট্রেভর রবিনসনের কাছ থেকে উদ্ধৃতিগুলির পরিবর্তে ডাবল উদ্ধৃতি যুক্ত করুন add আপনি যদি ডাবল উক্তিগুলি মিস করেন তবে আপনি "প্রধান শ্রেণীর সন্ধান করতে বা লোড করতে পারেন না" ত্রুটি পেয়ে যাবেন।


2
পূর্ববর্তী উত্তর অনুসারে, এটি জাভা in এ কাজ করে Java জাভা এর এই বৈশিষ্ট্যটি নেই।
জোশুয়া ডেভিস

5

আমি একটি উপায় খুঁজে বের করেছি যে কাজ করে। আপনি সরলফর্ম্যাটর সাবক্লাস করতে এবং ফর্ম্যাট পদ্ধতিটি ওভাররাইড করতে পারেন

    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

আপনি যদি টমক্যাট অ্যাড ব্যবহার করে কোনও ওয়েব অ্যাপ্লিকেশনটিতে লগইন করেন:

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

ভিএম যুক্তিতে


-3

আপনি যদি java.util.logging ব্যবহার করছেন, তবে কনফিগারেশন ফাইল রয়েছে যা লগ ইন করার জন্য এটি করছে (যদি না আপনি প্রোগ্রামিং কনফিগারেশন ব্যবহার করছেন)। সুতরাং, আপনার বিকল্পগুলি
1) পোস্ট-প্রসেসর চালান যা লাইন ব্রেকগুলি সরিয়ে দেয়
2) লগ কনফিগারেশন পরিবর্তন করে এবং এটি থেকে লাইন ব্রেকগুলি সরিয়ে দেয়। আপনার অ্যাপ্লিকেশন (সার্ভার) পুনরায় চালু করুন এবং আপনার ভাল হওয়া উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.