Создание нового файла журнала каждый день - PullRequest
13 голосов
/ 24 мая 2010

Как видно из названия, как я могу каждый день создавать новый файл журнала в C #?Теперь программа может работать не всегда днем ​​и ночью, а вызываться только в рабочее время.Поэтому мне нужно сделать две вещи.

  1. Как я могу создавать новый файл журнала каждый день?Файл журнала будет иметь имя в таком формате, как MMDDYYYY.txt
  2. Как я могу создать его сразу после полуночи, если он работает во все часы ночи?

Ответы [ 10 ]

39 голосов
/ 24 мая 2010

Обновление 2018: я предпочитаю использовать NLog сейчас

Предыдущий ответ о log4net:

В этом примере показано, как настроить RollingFileAppender для прокрутки файлов журнала за определенный период. Этот пример будет катить файл журнала каждую минуту! Чтобы изменить скользящий период, настройте значение DatePattern. Например, шаблон даты «yyyyMMdd» будет катиться каждый день.
См. System.Globalization.DateTimeFormatInfo для получения списка доступных шаблонов.

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\temp\rolling.log" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="yyyyMMdd-HHmm" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
</appender>
8 голосов
/ 24 мая 2010

Другие упоминали Log4Net, поэтому я продолжу и расшифрую Корпоративную библиотеку Блок журналирования, который также вполне способен делать то, что вы хотите.

Не могли бы вы включить код, показывающий, как легко было бы делать этот бросок каждый день?Это проще, чем пример log4Net? - Даниэль Дайсон

Конечно.Как правило, для построения конфигурации можно использовать Enterprise Library Configuration Tool ;к этому инструменту нужно немного привыкнуть, но как только вы поймете, как он работает, он довольно мощный.Тем не менее, вы также можете редактировать app.config вручную.

Вот выходные данные упомянутого мною инструмента, который сбрасывает практически все в виде плоского файла, который катится каждый день (или если он превышает 2 МБ).Форматирование по умолчанию предоставляется инструментом.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    </configSections>
    <loggingConfiguration name="" tracingEnabled="true" defaultCategory="Category">
        <listeners>
            <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                formatter="Text Formatter" rollInterval="Day" rollSizeKB="2000" />
        </listeners>
        <formatters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
                name="Text Formatter" />
        </formatters>
        <categorySources>
            <add switchValue="All" name="Category">
                <listeners>
                    <add name="Rolling Flat File Trace Listener" />
                </listeners>
            </add>
        </categorySources>
        <specialSources>
            <allEvents switchValue="All" name="All Events">
                <listeners>
                    <add name="Rolling Flat File Trace Listener" />
                </listeners>
            </allEvents>
            <notProcessed switchValue="All" name="Unprocessed Category">
                <listeners>
                    <add name="Rolling Flat File Trace Listener" />
                </listeners>
            </notProcessed>
            <errors switchValue="All" name="Logging Errors &amp; Warnings">
                <listeners>
                    <add name="Rolling Flat File Trace Listener" />
                </listeners>
            </errors>
        </specialSources>
    </loggingConfiguration>
</configuration>
8 голосов
/ 24 мая 2010

Я бы порекомендовал что-то вроде этого:

string logFile = DateTime.Now.ToString("yyyyMMdd") + ".txt";
if (!System.IO.File.Exists(logFile))
{
    System.IO.File.Create(logFile);   
}
//append to logFile here...

Есть ли причина, по которой вы хотите что-то создать после полуночи?Почему бы просто не создать его, если он не существует, когда вы регистрируете ошибку?

Также заметил, что я изменил формат даты.Это позволит вам сортировать файлы по имени и приводить их в порядок.Я всегда использую этот формат, когда возиться с датами в любом случае.

6 голосов
/ 24 мая 2010

Попробуйте NLog ( nlog-project.org ).По моему мнению, он очень гибкий и с ним легче работать.

Пример NLog.config:

<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets>
        <target name="file" xsi:type="File"
            layout="${longdate} ${logger} ${message}" 
            fileName="${basedir}/${shortdate}/${windows-identity:domain=false}.${level}.log" />
    </targets>

    <rules>
        <logger name="*" minlevel="Debug" writeTo="file" />
    </rules>
</nlog>

Дополнительные примеры (включая другие цели ведения журналов, кроме File), см. Примеры конфигурации NLog на Github

3 голосов
/ 07 ноября 2012

Ниже приведен XML-код приложения, который я сейчас использую.

На основании ваших требований
1) создание файла журнала один раз в день и
2) иметь расширение txt,
Вы должны использовать XML, аналогичный приведенному ниже.
Приведенный ниже XML создаст файл журнала с именем system-20121106.txt.

Единственная проблема заключается в том, что, поскольку значением файла является logs / system, ваш файл во время записи на текущий день будет system-. Чтобы обойти это, вам нужно установить значение файла в logs / system.txt, но тогда вы получите system.txt.20121106.txt в качестве окончательного файла

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="logs/system-" />
  <appendToFile value="true"/>
  <countDirection value="-1"/>
  <rollingStyle value="Date" />
  <datePattern value="yyyyMMdd'.txt'" />
  <maxSizeRollBackups value="0" />
  <maximumFileSize value="10000KB" />
  <staticLogFileName value="false" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%d [%t] %-5p %c - %m%n" />
  </layout>
</appender>
3 голосов
/ 24 мая 2010

использовать log4net .Это одна из наиболее часто используемых библиотек для ведения журнала.

Она может быть легко настроена, как вам нравится, см. Примеры.

3 голосов
/ 24 мая 2010

Вам не нужно создавать его в определенное время - в простейшем случае вы можете просто проверить, существует ли файл журнала с сегодняшней датой в качестве его имени, когда вы запускаете службу регистрации для приложения, и если нетвы можете создать его до того, как начнете добавлять к нему.

Единственный случай, когда вам нужно особенно помнить об этой настройке, - это когда приложение работает после полуночи.

1 голос
/ 24 мая 2010

Когда вы что-то регистрируете, проверьте, существует ли файл с текущей датой, если нет - создайте его.Все просто:)

if(fileExists(todaysDate + ".txt")){
  appendToLogFile(message);
}else{
  createFile(todaysDate + ".txt");
  appendToLogFile(message);
}
0 голосов
/ 20 октября 2018

Если вам нужен только простой TraceListener, у меня есть мини-реализация здесь: https://github.com/datvm/DailyTraceListener

Выход также в формате CSV, так что вы можете читать его в Excel или любом приложении для чтения CSV.*

Исходный код для TraceListener:

public class DailyTraceListener : TraceListener
{

    public bool UseUtcTime { get; private set; }
    public string LogFolder { get; private set; }
    public bool Disposed { get; private set; }
    public bool HasHeader { get; private set; }

    public string CurrentLogFilePath { get; private set; }

    protected DateTime? CurrentLogDate { get; set; }
    protected FileStream LogFileStream { get; set; }
    protected StreamWriter LogFileWriter { get; set; }

    private SemaphoreSlim LogLocker { get; set; } = new SemaphoreSlim(1, 1);

    public DailyTraceListener(string logFolder)
    {
        this.LogFolder = logFolder;
    }

    public DailyTraceListener UseUtc()
    {
        this.UseUtcTime = true;

        return this;
    }

    public DailyTraceListener UseHeader()
    {
        this.HasHeader = true;
        return this;
    }

    protected virtual void WriteHeader()
    {
        this.LogFileWriter.WriteLine(string.Format("{0},{1},{2},{3},{4}",
            "Time",
            "Type",
            "Source",
            "ID",
            "Message"));
    }

    protected virtual string FormatTime(DateTime time)
    {
        return time.ToString("o");
    }

    private DateTime GetCurrentTime()
    {
        if (this.UseUtcTime)
        {
            return DateTime.UtcNow;
        }
        else
        {
            return DateTime.Now;
        }
    }

    private void InitializeLogFile()
    {
        this.CheckDisposed();

        try
        {
            if (this.LogFileWriter != null)
            {
                this.LogFileWriter.Dispose();
            }

            if (this.LogFileStream != null)
            {
                this.LogFileWriter.Dispose();
            }
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }

        var currentTime = this.GetCurrentTime();

        var fileName = $"{currentTime.ToString("yyyy-MM-dd")}.log";
        this.CurrentLogFilePath = Path.Combine(this.LogFolder, fileName);

        // Ensure the folder is there
        Directory.CreateDirectory(this.LogFolder);

        // Create/Open log file
        this.LogFileStream = new FileStream(this.CurrentLogFilePath, FileMode.Append);
        this.LogFileWriter = new StreamWriter(this.LogFileStream);

        // Write Header if needed
        if (this.LogFileStream.Length == 0 && this.HasHeader)
        {
            this.WriteHeader();
        }
    }

    private void CheckFile()
    {
        this.CheckDisposed();

        var currentTime = this.GetCurrentTime();

        if (this.CurrentLogDate == null || currentTime.Date != this.CurrentLogDate)
        {
            this.InitializeLogFile();
            this.CurrentLogDate = currentTime.Date;
        }
    }

    private void CheckDisposed()
    {
        if (this.Disposed)
        {
            throw new InvalidOperationException("The Trace Listener is Disposed.");
        }
    }

    public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
    {
        var time = this.FormatTime(this.GetCurrentTime());
        this.WriteLine(string.Format("{0},{1},{2},{3},{4}",
            time,
            eventType,
            EscapeCsv(source),
            id.ToString(),
            EscapeCsv(message)));
    }

    public override void Write(string message)
    {
        try
        {
            this.LogLocker.Wait();

            this.CheckDisposed();
            this.CheckFile();

            var currentTime = this.GetCurrentTime();
            this.LogFileWriter.Write(message);
            this.LogFileWriter.Flush();
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }
        finally
        {
            this.LogLocker.Release();
        }
    }

    public override void WriteLine(string message)
    {
        this.Write(message + Environment.NewLine);
    }

    protected string EscapeCsv(string input)
    {
        for (int i = 0; i < input.Length; i++)
        {
            if (input[i] == ',' || input[i] == '\n')
            {
                input = input.Replace("\"", "\"\"");
                return $"\"{input}\"";
            }
        }

        return input;
    }

    protected override void Dispose(bool disposing)
    {
        this.Disposed = true;

        try
        {
            this.LogFileWriter?.Dispose();
            this.LogFileStream?.Dispose();
            this.LogLocker.Dispose();
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.ToString());
        }

        base.Dispose(disposing);
    }

}
0 голосов
/ 24 мая 2010

Нет необходимости создавать его, пока он вам не понадобится, используйте:

 file = new StreamWriter(path, true, new UTF8Encoding(false));

(или, возможно, другая кодировка.) Это создаст файл, если он не существует, или начнет добавлять к нему.

Тогда нужно создать имя файла и просто использовать его.

...