2012-04-20 17 views
30

मैं एक उपकरण लिख रहा हूं जो नेटवर्क पर वर्कस्टेशन के स्वास्थ्य की जांच करने जा रहा है, और जो मुद्दों को पाता है उसके अनुसार ठीक हो जाएगा। मैं एक लॉग फ़ाइल बनाना चाहता हूं क्योंकि ऐप प्रत्येक मशीन पर अपने कार्यों/चेक के माध्यम से चल रहा है। मैं बस इसे एक मशीन पर काम करना चाहता हूं, लेकिन समय में यह 100+ मशीनों को एक बार (थ्रेड आउट) में स्कैन करेगा।सी # लॉग फ़ाइल बनाने के लिए सबसे अच्छा तरीका

लॉग फ़ाइल बनाने का सबसे अच्छा तरीका क्या है?

मैं स्मृति में लॉग फ़ाइल बनाने के लिए List<string> का उपयोग करने के बारे में सोच रहा था और फिर इसे समाप्त होने के बाद फ़ाइल में आउटपुट कर रहा था।

मैं बस सोच रहा हूं कि ऐसा करने का एक बेहतर तरीका हो सकता है?

+0

मैं भी –

+1

इच्छुक हूँ वहाँ केवल एक ही आवेदन चल रहा है कि सभी मशीनों दूर से स्कैनिंग है या आपके एप्लिकेशन को व्यक्तिगत रूप से प्रत्येक मशीन पर तैनात किया जाएगा है? –

+0

आप एक लॉग फ़ाइल या प्रति मशीन बनाना चाहते हैं? – Reniuz

उत्तर

7

मैं तीसरे पक्ष के पुस्तकालयों का उपयोग नहीं करता, मैं एक एक्सएमएल फ़ाइल में लॉग इन करता हूं।

private static readonly object Locker = new object(); 
    private static XmlDocument _doc = new XmlDocument(); 
    static void Main(string[] args) 
    { 
     if (File.Exists("logs.txt")) 
      _doc.Load("logs.txt"); 
     else 
     { 
      var root = _doc.CreateElement("hosts"); 
      _doc.AppendChild(root); 
     } 
     for (int i = 0; i < 100; i++) 
     { 
      new Thread(new ThreadStart(DoSomeWork)).Start(); 
     } 
    } 
    static void DoSomeWork() 
    { 
     /* 

     * Here you will build log messages 

     */ 
     Log("192.168.1.15", "alive"); 
    } 
    static void Log(string hostname, string state) 
    { 
     lock (Locker) 
     { 
      var el = (XmlElement)_doc.DocumentElement.AppendChild(_doc.CreateElement("host")); 
      el.SetAttribute("Hostname", hostname); 
      el.AppendChild(_doc.CreateElement("State")).InnerText = state; 
      _doc.Save("logs.txt"); 
     } 
    } 
+0

आम तौर पर मैं असहमत हूं और लॉग 4नेट या एंटरप्राइज़ लाइब्रेरी का उपयोग कहूंगा ... व्हील को फिर से क्यों शुरू करें। लेकिन यह समाधान स्थिति के लिए सरल और उपयुक्त है, और यदि आपने पहले उन समाधानों का उपयोग नहीं किया है, तो यह संभवतः दस्तावेज़ों को पढ़ने और उन्हें कॉन्फ़िगर करने से तेज़ है। बहुत बढ़िया! –

+2

-1 - मैं कोई नेट विशेषज्ञ नहीं हूं लेकिन ऐसा लगता है कि आप प्रत्येक लॉग के लिए डिस्क पर पूरी लॉग फ़ाइल को 'लॉग (स्ट्रिंग, स्ट्रिंग)' में सहेज रहे हैं, न कि केवल लॉग फ़ाइल की प्रति बना रहे हैं '_doc' में स्मृति जो निश्चित रूप से एक अच्छा विचार नहीं है। –

+3

गैरेथ, यदि एप्लिकेशन में कोई क्रैश है, तो प्रक्रिया मारे जाती है, या कंप्यूटर पुनरारंभ होता है और प्रत्येक कॉल के लिए लॉग सहेजे नहीं जाते हैं, तो हम वास्तव में परेशानी में हैं। स्मृति के बारे में मुझे लगता है कि प्रत्येक लॉग (स्ट्रिंग, स्ट्रिंग) कॉल (100 धागे के बारे में सोचें) के लिए xml दस्तावेज़ लोड करने के लिए इसे और अधिक स्मृति खर्च होगी। – croisharp

5

आप इवेंट लॉग का उपयोग करना चाह सकते हैं! यहाँ कैसे बल्कि जब आपके प्रक्रिया रास्ते से सी # http://support.microsoft.com/kb/307024/en

लेकिन जो कुछ भी विधि है कि आप का उपयोग करेगा, मैं एक फ़ाइल हर बार कुछ लॉग में जोड़ा जाता है करने के लिए उत्पादन के लिए सलाह देते हैं से उस तक पहुंच है, तो आप जीत लिया है दुर्घटना के मामले में डेटा खोना नहीं है या यदि आपकी प्रक्रिया मारे गए हैं।

2

आप http://logging.apache.org/ लाइब्रेरी का उपयोग कर सकते हैं और अपनी सभी लॉग जानकारी एकत्र करने के लिए डेटाबेस एपेंडर का उपयोग कर सकते हैं।

3

आप अंतर्निहित .NET ट्रेसिंग सुविधाओं को भी देख सकते हैं। ट्रेस श्रोताओं का एक सेट है जो आपको लॉग फ़ाइल में आउटपुट करने की अनुमति देता है, लेकिन आप इसे इवेंट व्यूअर में लॉग इन करने के लिए कॉन्फ़िगर कर सकते हैं, या डेटाबेस (या उनमें से सभी एक साथ)।

http://www.codeguru.com/csharp/.net/net_debugging/tracing/article.php/c5919/NET-Tracing-Tutorial.htm

5

उपयोग Nlog http://nlog-project.org/। यह मुफ़्त है और फ़ाइल, डेटाबेस, इवेंट लॉग और अन्य 20+ लक्ष्यों को लिखने की अनुमति देता है। अन्य लॉगिंग ढांचा log4net है - http://logging.apache.org/log4net/ (जावा लॉग 4j प्रोजेक्ट से पोर्ट किया गया)। यह भी मुफ़्त है।

सर्वश्रेष्ठ अभ्यास आम लॉगिंग उपयोग करने के लिए कर रहे हैं - http://commons.apache.org/logging/ तो आप बाद में NLog या log4net अन्य प्रवेश ढांचे को बदल सकते हैं।

11

देख रहा log4net की सिफारिश करेंगे।

आपको एकाधिक लॉग फ़ाइलों की आवश्यकता होगी। तो एकाधिक फ़ाइल परिशिष्ट। इसके अलावा आप फ़ाइल एपेंडर गतिशील रूप से बना सकते हैं।

नमूना कोड:

using log4net; 
using log4net.Appender; 
using log4net.Layout; 
using log4net.Repository.Hierarchy; 

// Set the level for a named logger 
public static void SetLevel(string loggerName, string levelName) 
{ 
    ILog log = LogManager.GetLogger(loggerName); 
    Logger l = (Logger)log.Logger; 

    l.Level = l.Hierarchy.LevelMap[levelName]; 
    } 

// Add an appender to a logger 
public static void AddAppender(string loggerName, IAppender appender) 
{ 
    ILog log = LogManager.GetLogger(loggerName); 
    Logger l = (Logger)log.Logger; 

    l.AddAppender(appender); 
} 

// Create a new file appender 
public static IAppender CreateFileAppender(string name, string fileName) 
{ 
    FileAppender appender = new 
     FileAppender(); 
    appender.Name = name; 
    appender.File = fileName; 
    appender.AppendToFile = true; 

    PatternLayout layout = new PatternLayout(); 
    layout.ConversionPattern = "%d [%t] %-5p %c [%x] - %m%n"; 
    layout.ActivateOptions(); 

    appender.Layout = layout; 
    appender.ActivateOptions(); 

    return appender; 
} 

// In order to set the level for a logger and add an appender reference you 
// can then use the following calls: 
SetLevel("Log4net.MainForm", "ALL"); 
AddAppender("Log4net.MainForm", CreateFileAppender("appenderName", "fileName.log")); 

// repeat as desired 

सूत्रों का कहना है/अच्छा लिंक:

Log4Net: Programmatically specify multiple loggers (with multiple file appenders)

Adding appenders programmatically

How to configure log4net programmatically from scratch (no config)

प्लस लॉग 4नेट भी इवेंट लॉग में लिखने की अनुमति देता है। सबकुछ कॉन्फ़िगरेशन आधारित है, और विन्यास को रनटाइम पर xml से गतिशील रूप से लोड किया जा सकता है।

संपादित करें 2:

एक मक्खी पर लॉग फ़ाइलें स्विच करने के लिए जिस तरह से: log4net विन्यास फाइल वातावरण चर का समर्थन करता है:

Environment.SetEnvironmentVariable("log4netFileName", "MyApp.log"); 

और log4net config में:

<param name="File" value="${log4netFileName}".log/> 
+0

इसके लिए बहुत बहुत धन्यवाद, बहुत सराहना की। – Derek

4

आप इस्तेमाल कर सकते हैं Apache log4net library:

using System; 
using log4net; 
using log4net.Config; 


public class MyApp 
{ 
    // Define a static logger variable so that it references the 
    // Logger instance named "MyApp". 
    private static readonly ILog log = LogManager.GetLogger(typeof(MyApp)); 
    static void Main(string[] args) 
    { 
     XmlConfigurator.Configure(new System.IO.FileInfo(@"..\..\resources\log4net.config")); 
     log.Info("Entering application."); 
     Console.WriteLine("starting........."); 
     log.Info("Entering application."); 
     log.Error("Exiting application."); 
     Console.WriteLine("starting........."); 
    } 
} 
4

इस कॉन्फ़िग फ़ाइल


जोड़ने

यह एक कोड नमूना है कि विभिन्न धागे से एक xml फ़ाइल के लिए लॉग इन करने है

************************************************************************************* 
<!--Configuration for file appender--> 

<configuration> 
    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
    </configSections> 
    <log4net> 
    <appender name="FileAppender" type="log4net.Appender.FileAppender"> 
     <file value="logfile.txt" /> 
     <appendToFile value="true" /> 
     <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%d [%t] %-5p [%logger] - %m%n" /> 
     </layout> 
    </appender> 
    <root> 
     <level value="DEBUG" /> 
     <appender-ref ref="FileAppender" /> 
    </root> 
    </log4net> 
</configuration> 

************************************************************************************* 

<!--Configuration for console appender--> 


<configuration> 

    <configSections> 
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, 
     log4net" /> 
    </configSections> 

    <log4net> 
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" > 
     <layout type="log4net.Layout.PatternLayout"> 
     <param name="ConversionPattern" value="%d [%t] %-5p [%logger] - %m%n" /> 
     </layout> 
    </appender> 
    <root> 
     <level value="ALL" /> 
     <appender-ref ref="ConsoleAppender" /> 
    </root> 
    </log4net> 
</configuration> 
1

मैं उपयोग कर रहा हूँ थ्रेड सुरक्षित स्थिर कक्षा। मुख्य विचार सूची में संदेश कतार करना है और फिर प्रत्येक अवधि की लॉग फ़ाइल या प्रत्येक काउंटर सीमा को लॉग फ़ाइल में सहेजना है।

महत्वपूर्ण: आप फ़ाइल को सहेजने के लिए मजबूर करना चाहिए (DirectLog.SaveToFile();) जब आप प्रोग्राम से बाहर निकलें। (मामले में वहाँ अभी भी सूची पर कुछ आइटम हैं कि)

उपयोग बहुत सरल है: DirectLog.Log("MyLogMessage", 5);

यह मेरा कोड है:

using System; 
using System.IO; 
using System.Collections.Generic; 

namespace Mendi 
{ 

    /// <summary> 
    /// class used for logging misc information to log file 
    /// written by Mendi Barel 
    /// </summary> 
    static class DirectLog 
    { 
     readonly static int SAVE_PERIOD = 10 * 1000;// period=10 seconds 
     readonly static int SAVE_COUNTER = 1000;// save after 1000 messages 
     readonly static int MIN_IMPORTANCE = 0;// log only messages with importance value >=MIN_IMPORTANCE 

     readonly static string DIR_LOG_FILES = @"z:\MyFolder\"; 

     static string _filename = DIR_LOG_FILES + @"Log." + DateTime.Now.ToString("yyMMdd.HHmm") + @".txt"; 

     readonly static List<string> _list_log = new List<string>(); 
     readonly static object _locker = new object(); 
     static int _counter = 0; 
     static DateTime _last_save = DateTime.Now; 

     public static void NewFile() 
     {//new file is created because filename changed 
      SaveToFile(); 
      lock (_locker) 
      { 

       _filename = DIR_LOG_FILES + @"Log." + DateTime.Now.ToString("yyMMdd.HHmm") + @".txt"; 
       _counter = 0; 
      } 
     } 
     public static void Log(string LogMessage, int Importance) 
     { 
      if (Importance < MIN_IMPORTANCE) return; 
      lock (_locker) 
      { 
       _list_log.Add(String.Format("{0:HH:mm:ss.ffff},{1},{2}", DateTime.Now, LogMessage, Importance)); 
       _counter++; 
      } 
      TimeSpan timeDiff = DateTime.Now - _last_save; 

      if (_counter > SAVE_COUNTER || timeDiff.TotalMilliseconds > SAVE_PERIOD) 
       SaveToFile(); 
     } 

     public static void SaveToFile() 
     { 
      lock (_locker) 
       if (_list_log.Count == 0) 
       { 
        _last_save = _last_save = DateTime.Now; 
        return; 
       } 
      lock (_locker) 
      { 
       using (StreamWriter logfile = File.AppendText(_filename)) 
       { 

        foreach (string s in _list_log) logfile.WriteLine(s); 
        logfile.Flush(); 
        logfile.Close(); 
       } 

       _list_log.Clear(); 
       _counter = 0; 
       _last_save = DateTime.Now; 
      } 
     } 


     public static void ReadLog(string logfile) 
     { 
      using (StreamReader r = File.OpenText(logfile)) 
      { 
       string line; 
       while ((line = r.ReadLine()) != null) 
       { 
        Console.WriteLine(line); 
       } 
       r.Close(); 
      } 
     } 
    } 
} 
+0

फ़ाइल पर लॉक करना आवश्यक है तो इसे समझने के लिए एक पृष्ठ (गंभीरता से क्रमबद्ध करें) को सॉर्ट करें। Thread.Sleep (1)! इस तथ्य को लॉक करें कि आप फ़ाइल को लिखने के लिए नहीं खोल सकते हैं। फाइल आपका लॉक होगा। यह क्रॉस थ्रेड, प्रक्रिया, अनुप्रयोग, सर्वर, ... सुरक्षित है। किसी ऑब्जेक्ट पर लॉक करना केवल प्रक्रिया सुरक्षित है। – TamusJRoyce

संबंधित मुद्दे