লগ 4 জে স্ট্যাকট্রেস কীভাবে প্রেরণ করবেন?


152

যদি আপনি একটি e.printStackTrace () করেন তবে আপনি একটি ব্যতিক্রম ধরা এবং স্ট্যান্ডার্ড আউটপুট (যেমন, বলুন, কনসোল) এ নিম্নলিখিতটি পান :

java.io.FileNotFoundException: so.txt
        at java.io.FileInputStream.<init>(FileInputStream.java)
        at ExTest.readMyFile(ExTest.java:19)
        at ExTest.main(ExTest.java:7)

এখন আমি এটি পরিবর্তে একটি লগারে যেমন পাঠাতে চাই, লগ 4j নিম্নলিখিতটি পেতে:

31947 [AWT-EventQueue-0] ERROR Java.io.FileNotFoundException: so.txt
32204 [AWT-EventQueue-0] ERROR    at java.io.FileInputStream.<init>(FileInputStream.java)
32235 [AWT-EventQueue-0] ERROR    at ExTest.readMyFile(ExTest.java:19)
32370 [AWT-EventQueue-0] ERROR    at ExTest.main(ExTest.java:7)

কিভাবে আমি এটি করতে পারব?

try {
   ...
} catch (Exception e) {
    final String s;
    ...  // <-- What goes here?
    log.error( s );
}

উত্তর:


262

আপনি সরাসরি লগারে ব্যতিক্রমটি পাস করেন, যেমন

try {
   ...
} catch (Exception e) {
    log.error( "failed!", e );
}

স্ট্যাক ট্রেস রেন্ডার করতে এটি লগ 4 জে to


32
লগার তার প্রথম আর্গুমেন্টের জন্য একটি অবজেক্ট নেয় এবং এটি স্ট্রিং করে ()। তবে দ্বিতীয় যুক্তিটি থ্রোয়েবল হতে হবে এবং স্ট্যাকের ট্রেস প্রদর্শন করে।
পিটার লরি

1
আমি প্রথম স্ট্রিংয়ের মধ্যে কী স্টাফ করবেন তা আমি কখনই জানি না, সাধারণত আমি শেষ করে log.error(e.getLocalizedMessage(), e)যা সম্পূর্ণ অপ্রয়োজনীয়। এটি কি প্রথম আর্গুমেন্টের জন্য নাল পরিচালনা করে?
পিটারস

5
@ মার্ক: এটি একটি বার্তা দেওয়ার চেষ্টা করুন যা ব্যাতিক্রমের বার্তার চেয়ে প্রসঙ্গে বেশি প্রাসঙ্গিক, উদাহরণস্বরূপ আসলে কী করার চেষ্টা করা হয়েছিল?
স্কাফম্যান

2
@ মার্ক পিটারস, একটি উত্তম উদাহরণ হ'ল বার্তা হিসাবে বর্তমান পদ্ধতিতে যুক্তিগুলি লগ করা, বা - ফাইলনটফাউন্ড ব্যতিক্রমের জন্য যে পথটি খোলার চেষ্টা করা হয়েছিল তার পুরো নাম। কোনটি যা আপনাকে যা ভুল তা খুঁজে পেতে সহায়তা করতে পারে - কেবল মনে করুন আপনি পরিস্থিতি ডিবাগ করতে পারবেন না।
থোরবজর্ন রাভন অ্যান্ডারসন

1
@ স্কাফম্যান: আসলে আমি ব্যবহার করছি log4j-1.2.8.jarএবং আমি stackTraceআমার লগ ফাইলে সমস্ত মুদ্রণ করতে চেয়েছিলাম তাই আপনি উল্লিখিত উপরে যেমন চেষ্টা করেছিলেন তবে এটি কেবল আমার লগ ফাইলেই মুদ্রণ করছে nullPointerException। আমি আমার কোড ব্যবহার করেছিলাম e.printStackTrace()এটি সমস্ত ট্রেস মুদ্রণ করে। কেন এই কোলাভারি?
যুবরাজ

9

যদি আপনি কোনও ব্যতিক্রম জড়িত না করে একটি স্ট্যাকট্রেস লগইন করতে চান তবে এটি করুন:

String message = "";

for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {                         
    message = message + System.lineSeparator() + stackTraceElement.toString();
}   
log.warn("Something weird happened. I will print the the complete stacktrace even if we have no exception just to help you find the cause" + message);

3
System.lineSeparator () এর জন্য +1, এটি আমাকে একটি স্ট্যাকট্রেস মুদ্রণ করতে সহায়তা করেছিল যা আমি একটি দূরবর্তী পরিষেবা থেকে প্রতিক্রিয়া হিসাবে পেয়েছি
স্টেফানি

1
আমি কী সন্ধান করেছি, তবে আপনার এখানে স্ট্রিংবিল্ডার ব্যবহার করা উচিত
জেরুস


4

এটা আমার সাথে ঘটেছিল এবং দরকারী হতে পারে। যদি আপনি এই কাজ

try {
   ...
} catch (Exception e) {
    log.error( "failed! {}", e );
}

আপনি ব্যতিক্রমের শিরোনাম পাবেন এবং পুরো স্ট্যাকট্রেসটি পাবেন না। কারণ লগার ভাববে যে আপনি কোনও স্ট্রিং পাশ করছেন। {}স্কাফম্যান যেমন বলেছে তেমনি এটি করুন


1
অবশ্যই আপনি এখানে পুরো স্ট্যাক ট্রেস পাবেন, তবে too too খুব মুদ্রিত হবে ভারব্যাটিম (কোনও বিকল্প ছাড়াই)?
k1eran

1
আমার বন্ধু তাই নিশ্চিত না! এটি আমার কাজ করে না, আমি কেবল শিরোনাম পেয়েছি। এটি লগ
4j

@ আইবারবেউ ঠিক আছে কারণ Throwable.toString()কোনও স্ট্যাকট্র্যাস ফেরত দেয় না। (ধরে নিচ্ছি আপনি কোনও লগার ব্যবহার করছেন যা জানে যে 'with}' দিয়ে কী করবে))

3

স্কাফম্যানের উত্তর অবশ্যই সঠিক উত্তর। যেমন সকল এটির পদ্ধতি error(), warn(), info(), debug()একটি দ্বিতীয় প্যারামিটার হিসাবে নিক্ষেপযোগ্য দিতে পারে:

try {
...
 } catch (Exception e) {
logger.error("error: ", e);
}

তবে, আপনি স্ট্রিংকে স্ট্রিং হিসাবেও উত্তোলন করতে পারেন। কখনও কখনও এটি কার্যকর হতে পারে যদি আপনি "{}" স্থানধারক ব্যবহার করে বিন্যাসের বৈশিষ্ট্যটি কাজে লাগাতে চান - পদ্ধতিটি দেখুন void info(String var1, Object... var2);এই ক্ষেত্রে আপনার স্ট্রিং হিসাবে স্ট্যাকট্রেস রয়েছে, তবে আপনি আসলে এটির মতো কিছু করতে পারেন:

try {
...
 } catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}

এটি প্যারামাইট্রাইজ করা বার্তা এবং স্ট্যাকট্রেসটি শেষে যেমন পদ্ধতিটির জন্য করবে তেমনভাবে মুদ্রণ করবে: logger.error("error: ", e);

আমি আসলে একটি ওপেন সোর্স লাইব্রেরি লিখেছিলাম যার স্ট্যাকট্রেস উত্তোলনের জন্য ইউটিলিটি স্ট্রিং হিসাবে স্ট্রিংস স্ট্যাকট্রেসের বাইরে কিছু শব্দকে চৌকসভাবে ফিল্টার করার বিকল্প রয়েছে with উদাহরণস্বরূপ, আপনি যদি প্যাকেজ উপসর্গটি নির্দিষ্ট করেন যে আপনি নিজের উত্তোলিত স্ট্যাকট্রাসে আগ্রহী কিছু অপ্রাসঙ্গিক অংশ থেকে ফিল্টার করে আপনাকে খুব কনসাইজ করা তথ্য দিয়ে চলে যান। এখানে নিবন্ধটির লিঙ্কটি রয়েছে যা গ্রন্থাগারটি কী কী উপযোগিতা রয়েছে এবং কোথায় এটি পাবে (মভেন আর্টিফেক্টস এবং গিটার উত্স হিসাবে উভয়) এবং কীভাবে এটি ব্যবহার করতে হবে তা ব্যাখ্যা করে। স্ট্যাক ট্রেস ফিল্টারিং সহ ওপেন সোর্স জাভা লাইব্রেরি, সাইলেন্ট স্ট্রিং পার্সিং ইউনিকোড রূপান্তরকারী এবং সংস্করণ তুলনা " স্ট্যাকট্রেস শোর ফিল্টার " অনুচ্ছেদ দেখুন


একটি সমাধিযুক্ত কিন্তু দুর্দান্ত উত্তর।
পেইন

ধন্যবাদ, @ পেয়েন আমি একটি দুর্দান্ত প্রতিক্রিয়াটির প্রশংসা করি
মাইকেল গ্যান্টম্যান

2

এই উত্তর জিজ্ঞাসা করা প্রশ্নের সাথে সম্পর্কিত না হলেও প্রশ্নের শিরোনামের সাথে সম্পর্কিত হতে পারে।

public class ThrowableTest {

    public static void main(String[] args) {

        Throwable createdBy = new Throwable("Created at main()");
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintWriter pw = new PrintWriter(os);
        createdBy.printStackTrace(pw);
        try {
            pw.close();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.debug(os.toString());
    }
}

অথবা

public static String getStackTrace (Throwable t)
{
    StringWriter stringWriter = new StringWriter();
    PrintWriter  printWriter  = new PrintWriter(stringWriter);
    t.printStackTrace(printWriter);
    printWriter.close();    //surprise no IO exception here
    try {
        stringWriter.close();
    }
    catch (IOException e) {
    }
    return stringWriter.toString();
}

অথবা

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
    logger.debug(stackTrace.getClassName()+ "  "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}


0

এটি ভাল লগ 4 জে ত্রুটি / ব্যতিক্রম লগিং হবে - স্প্লঙ্ক / অন্যান্য লগিং / পর্যবেক্ষণ দ্বারা এস / ডাব্লু read সবকিছুই মূল-মান জুটির ফর্ম। log4j ব্যতিক্রম আপত্তি থেকে স্ট্যাক ট্রেস পাবেনe

    try {
          ---
          ---
    } catch (Exception e) {
        log.error("api_name={} method={} _message=\"error description.\" msg={}", 
                  new Object[]{"api_name", "method_name", e.getMessage(), e});
    }


-1

আপনি বেলো কোড ব্যবহার করতে পারেন:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class LogWriterUtility {
    Logger log;

    public LogWriterUtility(Class<?> clazz) {
        log = LogManager.getLogger(clazz);
    }

public void errorWithAnalysis( Exception exception) {

        String message="No Message on error";
        StackTraceElement[] stackTrace = exception.getStackTrace();
        if(stackTrace!=null && stackTrace.length>0) {
            message="";
            for (StackTraceElement e : stackTrace) {
                message += "\n" + e.toString();
            }
        }
        log.error(message);


    }

}

এখানে আপনি কেবল কল করতে পারেন: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);

এটি আপনার লগে স্ট্যাকট্রেস মুদ্রণ করবে।


-2

এটি তৈরি করুন class:

public class StdOutErrLog {

private static final Logger logger = Logger.getLogger(StdOutErrLog.class);

public static void tieSystemOutAndErrToLog() {
    System.setOut(createLoggingProxy(System.out));
    System.setErr(createLoggingProxy(System.err));
}

public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
    return new PrintStream(realPrintStream) {
        public void print(final String string) {
            logger.info(string);
        }
        public void println(final String string) {
            logger.info(string);
        }
    };
}
}

আপনার কোড এ কল করুন

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