سؤال

لدينا العديد من المهام التي تعمل بشكل متزامن والتي يجب أن تستخدم نفس معلومات التكوين لـ log4j.يقومون جميعًا بإلقاء السجلات في ملف واحد باستخدام نفس المُلحق.هل هناك طريقة لجعل كل وظيفة تقوم بتسمية ملف السجل الخاص بها ديناميكيًا حتى تظل منفصلة؟

شكرًا
توم

هل كانت مفيدة؟

المحلول

هل يمكنك تمرير خاصية نظام Java لكل وظيفة؟إذا كان الأمر كذلك، يمكنك المعلمة مثل هذا:

java -Dmy_var=somevalue my.job.Classname

ثم في log4j.properties الخاص بك:

log4j.appender.A.File=${my_var}/A.log

يمكنك ملء خاصية نظام Java بقيمة من بيئة المضيف (على سبيل المثال) والتي من شأنها أن تحدد مثيل الوظيفة بشكل فريد.

نصائح أخرى

إذا كانت أسماء الوظائف معروفة مسبقًا، فيمكنك تضمين اسم الوظيفة عند إجراء استدعاء getLogger().يمكنك بعد ذلك ربط المُلحقين المختلفين بمسجلين مختلفين، باستخدام أسماء ملفات منفصلة (أو وجهات أخرى).

إذا لم تتمكن من معرفة اسم المهمة مسبقًا، فيمكنك تكوين المسجل في وقت التشغيل بدلاً من استخدام ملف التكوين:

FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);

لدينا شيء مماثل تم تنفيذه في نظامنا.نقوم بتخزين أدوات قطع الأشجار المحددة في HashMap وتهيئة المُلحقين لكل منهم حسب الحاجة.

هنا مثال:

public class JobLogger {
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>();
private static String m_filename = "...";  // Root log directory

public static synchronized void logMessage(String jobName, String message)
{
    Logger l = getJobLogger(jobName);
    l.info(message);
}

public static synchronized void logException(String jobName, Exception e)
{
    Logger l = getJobLogger(partner);
    l.info(e.getMessage(), e);
}

private static synchronized Logger getJobLogger(String jobName)
{
    Logger logger = m_loggers.get(jobName);
    if (logger == null) {
        Layout layout = new PatternLayout("...");
        logger = Logger.getLogger(jobName);
        m_loggers.put(jobName, logger);
        logger.setLevel(Level.INFO);
        try {
            File file = new File(m_filename);
            file.mkdirs();
            file = new File(m_filename + jobName + ".log");
            FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false);
            logger.removeAllAppenders();
            logger.addAppender(appender);
    }
        catch (Exception e)
    { ... }
    }
    return logger;
}
}

ثم لاستخدام هذا في عملك، عليك فقط استخدام إدخال سطر واحد مثل هذا:

JobLogger.logMessage(jobName, logMessage);

سيؤدي هذا إلى إنشاء ملف سجل واحد لكل اسم مهمة وإفلاته في الملف الخاص به مع اسم الوظيفة هذا في أي دليل تحدده.

يمكنك التلاعب بأنواع أخرى من المُلحقات وما شابه، كما هو مكتوب، سيستمر الإلحاق حتى تتم إعادة تشغيل JVM والذي قد لا يعمل إذا قمت بتشغيل نفس الوظيفة على خادم يعمل دائمًا، ولكن هذا يعطي فكرة عامة عن كيفية القيام بذلك عمل.

يمكنك تعيين كل مهمة NDC أو MDC ثم كتابة مُلحق يغير الاسم بناءً على قيمة NDC أو MDC.إن إنشاء مُلحق جديد ليس بالأمر الصعب للغاية.قد يكون هناك أيضًا مُلحق يناسب الفاتورة في صندوق الحماية log4j.ابدأ بالبحث http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/

يمكنك كتابة المُلحق الخاص بك والذي يشكل اسم الملف الخاص به، ربما باستخدام [File.createTempFile](http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String)) طريقة.إذا FileAppender تمت كتابة الفصل الدراسي بشكل صحيح، فيجب أن تكون قادرًا على تمديده — أو RollingFileAppender- وتجاوز getFile طريقة لإرجاع واحدة تختارها بناءً على الخصائص الجديدة التي ترغب في إضافتها.

بناء على com.shaditإجابة.إذا كان من الممكن تحديد كل مهمة من خلال الطريقة الرئيسية للفئة التي تم بدء تشغيلها، فيمكنك استخدام خاصية النظام sun.java.command الذي يحتوي على الاسم الكامل للفصل الذي بدأ.على سبيل المثال مثل هذا:

log4j.appender.LOGFILE.File=${sun.java.command}.log

أنا استخدامها جنبا إلى جنب مع TimestampFileAppender مثله:

log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log

بهذه الطريقة، عندما أقوم بالتطوير في Eclipse، أحصل على ملف سجل جديد لكل عملية جديدة أقوم بتشغيلها، ويتم تحديده بواسطة اسم الفئة مع الطريقة الرئيسية ووقت البدء.

توم يمكنك تحديد والملحقين لكل وظيفة.لنفترض أن لديك وظيفتين تتوافقان مع حزمتي جافا مختلفتين com.tom.firstbatch وcom.tom. Secondbatch، سيكون لديك شيء مثل هذا في log4j.xml:

   <category name="com.tom.firstbatch">
      <appender-ref ref="FIRST_APPENDER"/>
   </category>
   <category name="com.tom.secondtbatch">
      <appender-ref ref="SECOND_APPENDER"/>
   </category>

يمكنك تكوين log4j برمجياً عند تهيئة المهمة.

يمكنك أيضًا تعيين ملف log4j.properties في وقت التشغيل عبر إحدى خصائص النظام.من يدوي:

قم بتعيين متغير سلسلة المورد إلى قيمة log4j.configuration خاصية النظام.الطريقة المفضلة لتحديد ملف التهيئة الافتراضي هي من خلال خاصية النظام log4j.configuration.في حالة عدم تعريف خاصية النظام log4j.configuration، قم بتعيين مورد متغير السلسلة إلى قيمته الافتراضية "log4j.properties".

بافتراض أنك تقوم بتشغيل المهام من أوامر جافا مختلفة، فإن هذا سيمكنهم من استخدام ملفات log4j.properties مختلفة وأسماء ملفات مختلفة لكل منها.

بدون معرفة محددة بكيفية إدارة وظائفك، من الصعب تحديد ذلك!

يمكنك تنفيذ ما يلي:

  • حامل ThreadLocal لهوية وظيفتك.
  • قم بتمديد FileAppender، يجب أن يحتفظ FileAppender بخريطة تحتوي على QuietWriter لكل هوية وظيفية.في طريقة الإلحاق الفرعي، تحصل على هوية وظيفتك من ThreadLocal، وتبحث عن (أو تنشئ) QuietWriter وتكتب إليه...

يمكنني أن أرسل لك بعض الرموز عبر البريد إذا كنت ترغب في ذلك...

log4j.logger.com.foo.admin = ، adminfileappender log4j.logger.com.foo.report = ، reportFilePender

إنها طريقة أخرى للقيام بهذه المهمة..هنا com.foo.admin هو اسم الحزمة الكامل

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top