-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'trunk' into update-htmlunit
- Loading branch information
Showing
9 changed files
with
212 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using System; | ||
using System.IO; | ||
|
||
namespace OpenQA.Selenium.Internal.Logging | ||
{ | ||
/// <summary> | ||
/// Represents a log handler that writes log events to a file. | ||
/// </summary> | ||
public class FileLogHandler : ILogHandler, IDisposable | ||
{ | ||
// performance trick to avoid expensive Enum.ToString() with fixed length | ||
private static readonly string[] _levels = { "TRACE", "DEBUG", " INFO", " WARN", "ERROR" }; | ||
|
||
private FileStream _fileStream; | ||
private StreamWriter _streamWriter; | ||
|
||
private readonly object _lockObj = new object(); | ||
private bool _isDisposed; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="FileLogHandler"/> class with the specified file path. | ||
/// </summary> | ||
/// <param name="path">The path of the log file.</param> | ||
public FileLogHandler(string path) | ||
{ | ||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("File log path cannot be null or empty.", nameof(path)); | ||
|
||
var directory = Path.GetDirectoryName(path); | ||
if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory)) | ||
{ | ||
Directory.CreateDirectory(directory); | ||
} | ||
|
||
_fileStream = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); | ||
_fileStream.Seek(0, SeekOrigin.End); | ||
_streamWriter = new StreamWriter(_fileStream, System.Text.Encoding.UTF8) | ||
{ | ||
AutoFlush = true | ||
}; | ||
} | ||
|
||
/// <summary> | ||
/// Handles a log event by writing it to the log file. | ||
/// </summary> | ||
/// <param name="logEvent">The log event to handle.</param> | ||
public void Handle(LogEvent logEvent) | ||
{ | ||
lock (_lockObj) | ||
{ | ||
_streamWriter.WriteLine($"{logEvent.Timestamp:r} {_levels[(int)logEvent.Level]} {logEvent.IssuedBy.Name}: {logEvent.Message}"); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Disposes the file log handler and releases any resources used. | ||
/// </summary> | ||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
/// <summary> | ||
/// Finalizes the file log handler instance. | ||
/// </summary> | ||
~FileLogHandler() | ||
{ | ||
Dispose(false); | ||
} | ||
|
||
/// <summary> | ||
/// Disposes the file log handler and releases any resources used. | ||
/// </summary> | ||
/// <param name="disposing">A flag indicating whether to dispose managed resources.</param> | ||
protected virtual void Dispose(bool disposing) | ||
{ | ||
lock (_lockObj) | ||
{ | ||
if (!_isDisposed) | ||
{ | ||
if (disposing) | ||
{ | ||
_streamWriter?.Dispose(); | ||
_streamWriter = null; | ||
_fileStream?.Dispose(); | ||
_fileStream = null; | ||
} | ||
|
||
_isDisposed = true; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using NUnit.Framework; | ||
using System; | ||
using System.IO; | ||
|
||
namespace OpenQA.Selenium.Internal.Logging | ||
{ | ||
public class FileLogHandlerTest | ||
{ | ||
[Test] | ||
[TestCase(null)] | ||
[TestCase("")] | ||
public void ShouldNotAcceptIncorrectPath(string path) | ||
{ | ||
var act = () => new FileLogHandler(path); | ||
|
||
Assert.That(act, Throws.ArgumentException); | ||
} | ||
|
||
[Test] | ||
public void ShouldHandleLogEvent() | ||
{ | ||
var tempFile = Path.GetTempFileName(); | ||
|
||
try | ||
{ | ||
using (var fileLogHandler = new FileLogHandler(tempFile)) | ||
{ | ||
fileLogHandler.Handle(new LogEvent(typeof(FileLogHandlerTest), DateTimeOffset.Now, LogEventLevel.Info, "test message")); | ||
} | ||
|
||
Assert.That(File.ReadAllText(tempFile), Does.Contain("test message")); | ||
} | ||
catch (Exception) | ||
{ | ||
throw; | ||
} | ||
finally | ||
{ | ||
File.Delete(tempFile); | ||
} | ||
} | ||
} | ||
} |