32

ネットワーク全体のワークステーションの状態をチェックし、見つかった問題に応じて修正するツールを作成しています。アプリが各マシンでタスク/チェックを実行しているときにログファイルを作成したいと思います。今のところ、これを1台のマシンで動作させたいのですが、やがて100台以上のマシンを一度にスキャンするようになります(スレッド化)。

ログファイルを作成するための最良の方法は何ですか?

を使用List<string>してログファイルをメモリに構築し、終了したらファイルに出力することを考えていました。

私はこれを行うためのより良い方法があるかもしれないと思っていますか?

4

12 に答える 12

12

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:プログラムで複数のロガーを指定します(複数のファイルアペンダーを使用)

プログラムによるアペンダーの追加

log4netをプログラムで最初から構成する方法(構成なし)

さらに、log4netではイベントログへの書き込みも可能です。すべてが構成ベースであり、構成は実行時にxmlから動的にロードすることもできます。

編集2:

ログファイルをオンザフライで切り替える1つの方法:Log4Net構成ファイルは環境変数をサポートします。

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

およびlog4net構成:

<param name="File" value="${log4netFileName}".log/>
于 2012-04-20T07:59:06.233 に答える
8

サードパーティのライブラリは使用せず、xmlファイルにログインします。

これは、さまざまなスレッドからxmlファイルへのロギングを行うコードサンプルです。

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");
    }
}
于 2012-04-20T08:35:46.453 に答える
5

イベントログを使用することをお勧めします。C# http://support.microsoft.com/kb/307024/enからアクセスする方法は次の とおりです。

ただし、使用する方法が何であれ、プロセスが終了したときではなく、ログに何かが追加されるたびにファイルに出力することをお勧めします。これにより、クラッシュした場合やプロセスが発生した場合にデータが失われることはありません。殺されます。

于 2012-04-20T07:39:29.483 に答える
5

Nloghttp://nlog-project.org/を使用します。これは無料で、ファイル、データベース、イベントログ、その他の20以上のターゲットに書き込むことができます。他のロギングフレームワークはlog4netです-http ://logging.apache.org/log4net/(java Log4jプロジェクトから移植されました)。それも無料です。

ベストプラクティスは、共通のログを使用することです-http: //commons.apache.org/logging/ したがって、後でNLogまたはlog4netを他のログフレームワークに変更できます。

于 2012-04-20T07:52:57.783 に答える
5

ロギングについて多くの調査を行い、NLogを使用するのが最適であると判断しました。

http://nlog-project.org/を参照してください

log4netとNlog およびhttp://www.dotnetlogging.com/comparison/も参照してください。

于 2012-04-20T07:54:12.937 に答える
4

Apachelog4netライブラリを使用できます。

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.........");
    }
}
于 2012-06-18T10:10:24.930 に答える
4

この設定ファイルを追加します


*************************************************************************************
<!--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>
于 2012-06-18T10:45:01.543 に答える
3

組み込みの.NETトレース機能も確認できます。ログファイルに出力できる一連のトレースリスナーがありますが、イベントビューア、データベース(またはそれらすべてを同時に)にログインするように構成できます。

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

于 2012-04-20T07:45:11.227 に答える
2

http://logging.apache.org/ライブラリを使用し、データベースアペンダーを使用して、すべてのログ情報をまとめて収集できます。

于 2012-04-20T07:40:27.827 に答える
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();
            }
        }
    }
}
于 2013-10-02T22:27:04.880 に答える
0

GitHubのheiswayiSimpleLoggerが良いと思いました。

于 2017-11-15T08:42:00.357 に答える
0

外部ライブラリであるlog4netを使用する代わりに、高度にカスタマイズ可能で使いやすい独自の単純なクラスを作成しました(YOURNAMESPACEHERE必要な名前空間で編集します)。

コンソールアプリ

using System;
using System.IO;

namespace YOURNAMESPACEHERE
{
    enum LogEvent
    {
        Info = 0,
        Success = 1,
        Warning = 2,
        Error = 3
    }

    internal static class Log
    {
        private static readonly string LogSession = DateTime.Now.ToLocalTime().ToString("ddMMyyyy_HHmmss");
        private static readonly string LogPath = AppDomain.CurrentDomain.BaseDirectory + "logs";

        internal static void Write(LogEvent Level, string Message, bool ShowConsole = true, bool WritelogFile = true)
        {
            string Event = string.Empty;
            ConsoleColor ColorEvent = Console.ForegroundColor;

            switch (Level)
            {
                case LogEvent.Info:
                    Event = "INFO";
                    ColorEvent = ConsoleColor.White;
                    break;
                case LogEvent.Success:
                    Event = "SUCCESS";
                    ColorEvent = ConsoleColor.Green;
                    break;
                case LogEvent.Warning:
                    Event = "WARNING";
                    ColorEvent = ConsoleColor.Yellow;
                    break;
                case LogEvent.Error:
                    Event = "ERROR";
                    ColorEvent = ConsoleColor.Red;
                    break;
            }

            if (ShowConsole)
            {
                Console.ForegroundColor = ColorEvent;
                Console.WriteLine(" [{0}] => {1}", DateTime.Now.ToString("HH:mm:ss"), Message);
                Console.ResetColor();
            }

            if (WritelogFile)
            {
                if (!Directory.Exists(LogPath))
                    Directory.CreateDirectory(LogPath);

                File.AppendAllText(LogPath + @"\" + LogSession + ".log", string.Format("[{0}] => {1}: {2}\n", DateTime.Now.ToString("HH:mm:ss"), Event, Message));
            }
        }
    }
}

コンソールアプリなし(ログのみ)

using System;
using System.IO;

namespace YOURNAMESPACEHERE
{
    enum LogEvent
    {
        Info = 0,
        Success = 1,
        Warning = 2,
        Error = 3
    }

internal static class Log
{
    private static readonly string LogSession = DateTime.Now.ToLocalTime().ToString("ddMMyyyy_HHmmss");
    private static readonly string LogPath = AppDomain.CurrentDomain.BaseDirectory + "logs";

    internal static void Write(LogEvent Level, string Message)
    {
        string Event = string.Empty;

        switch (Level)
        {
            case LogEvent.Info:
                Event = "INFO";
                break;
            case LogEvent.Success:
                Event = "SUCCESS";
                break;
            case LogEvent.Warning:
                Event = "WARNING";
                break;
            case LogEvent.Error:
                Event = "ERROR";
                break;
        }

        if (!Directory.Exists(LogPath))
            Directory.CreateDirectory(LogPath);

        File.AppendAllText(LogPath + @"\" + LogSession + ".log", string.Format("[{0}] => {1}: {2}\n", DateTime.Now.ToString("HH:mm:ss"), Event, Message));
    }
}

使用法:

コンソールアプリ

Log.Write(LogEvent.Info, "Test message"); // It will print an info in your console, also will save a copy of this print in a .log file.
Log.Write(LogEvent.Warning, "Test message", false); // It will save the print as warning only in your .log file.
Log.Write(LogEvent.Error, "Test message", true, false); // It will print an error only in your console.

コンソールアプリなし(ログのみ)

Log.Write(LogEvent.Info, "Test message"); // It will print an info in your .log file.
于 2020-12-12T18:17:18.573 に答える