Self-Diagnostics: include datetimestamp in filename (#2325)

* include datetimestamp in self-diagnostics filename

* come review comments

* update readme

* update readme

* Update Readme.md
This commit is contained in:
Timothy Mothra 2021-07-09 17:47:38 -07:00 коммит произвёл GitHub
Родитель c68a4f4d83
Коммит 317786702e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 41 добавлений и 19 удалений

Просмотреть файл

@ -15,15 +15,16 @@
[TestMethod] [TestMethod]
public void MemoryMappedFileHandler_Success() public void MemoryMappedFileHandler_Success()
{ {
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "." string filePath;
+ Process.GetCurrentProcess().Id + ".log";
var fileSize = 1024; var fileSize = 1024;
using (var handler = new MemoryMappedFileHandler()) using (var handler = new MemoryMappedFileHandler())
{ {
handler.CreateLogFile(".", fileSize); handler.CreateLogFile(".", fileSize);
filePath = handler.CurrentFilePath;
} }
var actualBytes = ReadFile(fileName, MessageOnNewFile.Length); var actualBytes = ReadFile(filePath, MessageOnNewFile.Length);
CollectionAssert.AreEqual(MessageOnNewFile, actualBytes); CollectionAssert.AreEqual(MessageOnNewFile, actualBytes);
} }
@ -36,6 +37,8 @@
var messageToOverflow = Encoding.UTF8.GetBytes("1234567"); var messageToOverflow = Encoding.UTF8.GetBytes("1234567");
var expectedBytesAtEnd = Encoding.UTF8.GetBytes("1234"); var expectedBytesAtEnd = Encoding.UTF8.GetBytes("1234");
var expectedBytesAtStart = Encoding.UTF8.GetBytes("567cessfully opened file.\n"); var expectedBytesAtStart = Encoding.UTF8.GetBytes("567cessfully opened file.\n");
string filePath;
using (var handler = new MemoryMappedFileHandler()) using (var handler = new MemoryMappedFileHandler())
{ {
handler.CreateLogFile(".", fileSize); handler.CreateLogFile(".", fileSize);
@ -43,20 +46,20 @@
handler.Write(buffer, fileSize - MessageOnNewFile.Length - expectedBytesAtEnd.Length); handler.Write(buffer, fileSize - MessageOnNewFile.Length - expectedBytesAtEnd.Length);
handler.Write(messageToOverflow, messageToOverflow.Length); handler.Write(messageToOverflow, messageToOverflow.Length);
filePath = handler.CurrentFilePath;
} }
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "." var actualBytes = ReadFile(filePath, buffer.Length);
+ Process.GetCurrentProcess().Id + ".log";
var actualBytes = ReadFile(fileName, buffer.Length);
CollectionAssert.AreEqual(expectedBytesAtStart, SubArray(actualBytes, 0, expectedBytesAtStart.Length)); CollectionAssert.AreEqual(expectedBytesAtStart, SubArray(actualBytes, 0, expectedBytesAtStart.Length));
CollectionAssert.AreEqual(expectedBytesAtEnd, SubArray(actualBytes, actualBytes.Length - expectedBytesAtEnd.Length, expectedBytesAtEnd.Length)); CollectionAssert.AreEqual(expectedBytesAtEnd, SubArray(actualBytes, actualBytes.Length - expectedBytesAtEnd.Length, expectedBytesAtEnd.Length));
} }
private static byte[] ReadFile(string fileName, int byteCount) private static byte[] ReadFile(string filePath, int byteCount)
{ {
byte[] actualBytes = new byte[byteCount]; byte[] actualBytes = new byte[byteCount];
using (var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{ {
file.Read(actualBytes, 0, byteCount); file.Read(actualBytes, 0, byteCount);
} }

Просмотреть файл

@ -27,8 +27,10 @@
// Emitting event of EventLevel.Warning // Emitting event of EventLevel.Warning
CoreEventSource.Log.OperationIsNullWarning(); CoreEventSource.Log.OperationIsNullWarning();
var filePath = configRefresher.CurrentFilePath;
int bufferSize = 512; int bufferSize = 512;
byte[] actualBytes = ReadFile(bufferSize); byte[] actualBytes = ReadFile(filePath, bufferSize);
string logText = Encoding.UTF8.GetString(actualBytes); string logText = Encoding.UTF8.GetString(actualBytes);
Assert.IsTrue(logText.StartsWith(MessageOnNewFileString)); Assert.IsTrue(logText.StartsWith(MessageOnNewFileString));
@ -52,8 +54,10 @@
// Emitting event of EventLevel.Error // Emitting event of EventLevel.Error
CoreEventSource.Log.InvalidOperationToStopError(); CoreEventSource.Log.InvalidOperationToStopError();
var filePath = configRefresher.CurrentFilePath;
int bufferSize = 512; int bufferSize = 512;
byte[] actualBytes = ReadFile(bufferSize); byte[] actualBytes = ReadFile(filePath, bufferSize);
string logText = Encoding.UTF8.GetString(actualBytes); string logText = Encoding.UTF8.GetString(actualBytes);
Assert.IsTrue(logText.StartsWith(MessageOnNewFileString)); Assert.IsTrue(logText.StartsWith(MessageOnNewFileString));
@ -77,12 +81,9 @@
return logLine.Substring(timestampPrefixLength); return logLine.Substring(timestampPrefixLength);
} }
private static byte[] ReadFile(int byteCount) private static byte[] ReadFile(string filePath, int byteCount)
{ {
var outputFileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "." using (var file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ Process.GetCurrentProcess().Id + ".log";
var outputFilePath = Path.Combine(".", outputFileName);
using (var file = File.Open(outputFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{ {
byte[] actualBytes = new byte[byteCount]; byte[] actualBytes = new byte[byteCount];
file.Read(actualBytes, 0, byteCount); file.Read(actualBytes, 0, byteCount);

Просмотреть файл

@ -2,6 +2,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
{ {
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.IO.MemoryMappedFiles; using System.IO.MemoryMappedFiles;
using System.Text; using System.Text;
@ -38,6 +39,8 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
public int LogFileSize { get => this.logFileSize; private set => this.logFileSize = value; } public int LogFileSize { get => this.logFileSize; private set => this.logFileSize = value; }
public string CurrentFilePath => this.underlyingFileStreamForMemoryMappedFile?.Name;
/// <summary> /// <summary>
/// Create a log file. If the file already exists, it will be overwritten. /// Create a log file. If the file already exists, it will be overwritten.
/// </summary> /// </summary>
@ -48,8 +51,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
try try
{ {
Directory.CreateDirectory(logDirectory); Directory.CreateDirectory(logDirectory);
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "." var fileName = GenerateFileName();
+ Process.GetCurrentProcess().Id + ".log";
var filePath = Path.Combine(logDirectory, fileName); var filePath = Path.Combine(logDirectory, fileName);
// Because the API [MemoryMappedFile.CreateFromFile][1](the string version) behaves differently on // Because the API [MemoryMappedFile.CreateFromFile][1](the string version) behaves differently on
@ -162,6 +164,17 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
} }
} }
private static string GenerateFileName()
{
var dateTimeStamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss", CultureInfo.InvariantCulture);
var currentProcess = Process.GetCurrentProcess();
var processFileName = Path.GetFileName(currentProcess.MainModule.FileName);
var processId = currentProcess.Id;
return $"{dateTimeStamp}.{processFileName}.{processId}.log";
}
/// <summary> /// <summary>
/// Try to get the log stream which is seeked to the position where the next line of log should be written. /// Try to get the log stream which is seeked to the position where the next line of log should be written.
/// </summary> /// </summary>

Просмотреть файл

@ -37,6 +37,8 @@
this.worker = Task.Run(() => this.Worker(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token); this.worker = Task.Run(() => this.Worker(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token);
} }
public string CurrentFilePath => this.memoryMappedFileHandler.CurrentFilePath;
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {

Просмотреть файл

@ -122,7 +122,8 @@ As of version 2.18.0, this SDK ships a "self-diagnostics feature" which captures
The self-diagnostics feature can be enabled/changed/disabled while the process is running. The self-diagnostics feature can be enabled/changed/disabled while the process is running.
The SDK will attempt to read the configuration file every 10 seconds, using a non-exclusive read-only mode. The SDK will attempt to read the configuration file every 10 seconds, using a non-exclusive read-only mode.
The SDK will create or overwrite a file with new logs according to the configuration. The SDK will create or overwrite a file with new logs according to the configuration.
This file will not exceed the configured max size and will be circularly overwritten.
#### Configuration #### Configuration
@ -150,13 +151,15 @@ Example:
#### Configuration Parameters #### Configuration Parameters
A `FileSize`-KiB log file named as `ExecutableName.ProcessId.log` (e.g. `foobar.exe.12345.log`) will be generated at the specified directory `LogDirectory`. A `FileSize`-KiB log file named as `YearMonthDay-HourMinuteSecond.ExecutableName.ProcessId.log` (e.g. `20010101-120000.foobar.exe.12345.log`) will be generated at the specified directory `LogDirectory`.
The file name starts with the `DateTime.UtcNow` timestamp of when the file was created.
1. `LogDirectory` is the directory where the output log file will be stored. 1. `LogDirectory` is the directory where the output log file will be stored.
It can be an absolute path or a relative path to the current directory. It can be an absolute path or a relative path to the current directory.
2. `FileSize` is a positive integer, which specifies the log file size in [KiB](https://en.wikipedia.org/wiki/Kibibyte). 2. `FileSize` is a positive integer, which specifies the log file size in [KiB](https://en.wikipedia.org/wiki/Kibibyte).
This value must be between 1 MiB and 128 MiB (inclusive), or it will be rounded to the closest upper or lower limit. This value must be between 1 MiB and 128 MiB (inclusive), or it will be rounded to the closest upper or lower limit.
The log file will never exceed this configured size, and will be circularly rewriten.
3. `LogLevel` is the lowest level of the events to be captured. 3. `LogLevel` is the lowest level of the events to be captured.
This value must match one of the [fields](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel#fields) of the `EventLevel` enum. This value must match one of the [fields](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel#fields) of the `EventLevel` enum.