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]
public void MemoryMappedFileHandler_Success()
{
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "."
+ Process.GetCurrentProcess().Id + ".log";
string filePath;
var fileSize = 1024;
using (var handler = new MemoryMappedFileHandler())
{
handler.CreateLogFile(".", fileSize);
filePath = handler.CurrentFilePath;
}
var actualBytes = ReadFile(fileName, MessageOnNewFile.Length);
var actualBytes = ReadFile(filePath, MessageOnNewFile.Length);
CollectionAssert.AreEqual(MessageOnNewFile, actualBytes);
}
@ -36,6 +37,8 @@
var messageToOverflow = Encoding.UTF8.GetBytes("1234567");
var expectedBytesAtEnd = Encoding.UTF8.GetBytes("1234");
var expectedBytesAtStart = Encoding.UTF8.GetBytes("567cessfully opened file.\n");
string filePath;
using (var handler = new MemoryMappedFileHandler())
{
handler.CreateLogFile(".", fileSize);
@ -43,20 +46,20 @@
handler.Write(buffer, fileSize - MessageOnNewFile.Length - expectedBytesAtEnd.Length);
handler.Write(messageToOverflow, messageToOverflow.Length);
filePath = handler.CurrentFilePath;
}
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "."
+ Process.GetCurrentProcess().Id + ".log";
var actualBytes = ReadFile(fileName, buffer.Length);
var actualBytes = ReadFile(filePath, buffer.Length);
CollectionAssert.AreEqual(expectedBytesAtStart, SubArray(actualBytes, 0, expectedBytesAtStart.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];
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);
}

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

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

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

@ -2,6 +2,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.MemoryMappedFiles;
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 string CurrentFilePath => this.underlyingFileStreamForMemoryMappedFile?.Name;
/// <summary>
/// Create a log file. If the file already exists, it will be overwritten.
/// </summary>
@ -48,8 +51,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.Sel
try
{
Directory.CreateDirectory(logDirectory);
var fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName) + "."
+ Process.GetCurrentProcess().Id + ".log";
var fileName = GenerateFileName();
var filePath = Path.Combine(logDirectory, fileName);
// 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>
/// Try to get the log stream which is seeked to the position where the next line of log should be written.
/// </summary>

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

@ -37,6 +37,8 @@
this.worker = Task.Run(() => this.Worker(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token);
}
public string CurrentFilePath => this.memoryMappedFileHandler.CurrentFilePath;
/// <inheritdoc/>
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 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
@ -150,13 +151,15 @@ Example:
#### 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.
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).
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.
This value must match one of the [fields](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventlevel#fields) of the `EventLevel` enum.