// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. using System; using System.IO; using System.Text; using System.Diagnostics; using System.Threading; namespace Tools.CrashReporter.CrashReportCommon { /// /// Thread-safe log creation and writing for crash report processes /// public class LogWriter { /// /// Constructor: opens the log file /// /// Application name to prepend to log filename /// Folder in which to store log file public LogWriter(string AppNameParam, string LogFolderParam) { // Store the arguments for repeated log file creation AppName = AppNameParam; LogFolder = LogFolderParam; // Ensure the log folder exists DirectoryInfo DirInfo = new DirectoryInfo(LogFolder); if(!DirInfo.Exists) { DirInfo.Create(); } CreateNewLogFile(); } /// /// Shutdown: flush and close the log file /// public void Dispose() { lock( Sync ) { LogFile.Flush(); LogFile.Close(); LogFile = null; } } /// /// Write a line to the log file and to the console /// /// Text to write public void Print(string Line) { if (Line != null) { string FullLine = DateTime.UtcNow.ToString( "yyyy/MM/dd HH:mm:ss" ) + "UTC [" + Thread.CurrentThread.ManagedThreadId.ToString( "D3" ) + "] : " + Line; lock( Sync ) { LogFile.WriteLine( FullLine ); LogFile.Flush(); } // Relay to the console if it's available Console.WriteLine( FullLine ); if( System.Diagnostics.Debugger.IsAttached ) { Debug.WriteLine( FullLine ); } } } /// /// Clean out any old log files in the same directory as this log /// /// Files older than this many days will be deleted public void CleanOutOldLogs( int OlderThanDays ) { DirectoryInfo DirInfo = new DirectoryInfo(LogFolder); foreach(FileInfo LogFileInfo in DirInfo.GetFiles()) { if (LogFileInfo.LastWriteTimeUtc.AddDays(OlderThanDays) < DateTime.UtcNow) { LogFileInfo.Delete(); } } } /// /// Create either an initial log file or switch to a new, time-stamped log file /// public void CreateNewLogFile() { lock( Sync ) { var OldLogFile = LogFile; var LogFileName = Path.Combine( LogFolder, AppName + "-" + DateTime.UtcNow.ToString( "yyyy-MM-dd" ) + ".txt" ); // Create a threadsafe text writer LogFile = new StreamWriter( LogFileName, true, Encoding.UTF8 ); Print( AppName + ", Copyright 2014-2017 Epic Games, Inc." ); // Don't close the previous log file until the new one is up and running if( OldLogFile != null ) { OldLogFile.Flush(); OldLogFile.Close(); } } } /// Open file stream messages are written to volatile TextWriter LogFile; /// Application name to pre-pend to log filenames and put in copyright notice string AppName; /// Folder log has been created in string LogFolder; object Sync = new object(); } }