Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable the self diagnostics and fix a NullReferenceException bug #2302

Merged
merged 3 commits into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.SelfDiagnostics
{
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

Expand Down Expand Up @@ -55,9 +53,9 @@ public void SelfDiagnosticsEventListener_DateTimeGetBytes()
// Check DateTimeKind of Utc, Local, and Unspecified
DateTime[] datetimes = new DateTime[]
{
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00"), DateTimeKind.Utc),
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00"), DateTimeKind.Local),
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00"), DateTimeKind.Unspecified),
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00", CultureInfo.InvariantCulture), DateTimeKind.Utc),
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00", CultureInfo.InvariantCulture), DateTimeKind.Local),
DateTime.SpecifyKind(DateTime.Parse("1996-12-01T14:02:31.1234567-08:00", CultureInfo.InvariantCulture), DateTimeKind.Unspecified),
DateTime.UtcNow,
DateTime.Now,
};
Expand All @@ -76,14 +74,23 @@ public void SelfDiagnosticsEventListener_DateTimeGetBytes()
string[] results = new string[datetimes.Length];
for (int i = 0; i < datetimes.Length; i++)
{
int len = listener.DateTimeGetBytes(datetimes[i], buffer, pos);
int len = SelfDiagnosticsEventListener.DateTimeGetBytes(datetimes[i], buffer, pos);
results[i] = Encoding.Default.GetString(buffer, pos, len);
pos += len;
}

CollectionAssert.AreEqual(expected, results);
}

[TestMethod]
public void SelfDiagnosticsEventListener_EncodeInBuffer_Null()
{
byte[] buffer = new byte[20];
int startPos = 0;
int endPos = SelfDiagnosticsEventListener.EncodeInBuffer(null, false, buffer, startPos);
Assert.AreEqual(startPos, endPos);
}

[TestMethod]
public void SelfDiagnosticsEventListener_EncodeInBuffer_Empty()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ private void Dispose(bool disposing)
// Or it might have created another MemoryMappedFile in that thread
// after the Dispose() below is called.
this.memoryMappedFileHandler.Dispose();
if (this.eventListener != null)
{
this.eventListener.Dispose();
}
}

this.disposedValue = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public SelfDiagnosticsEventListener(EventLevel logLevel, MemoryMappedFileHandler
public override void Dispose()
{
this.Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}

Expand All @@ -71,6 +72,11 @@ public override void Dispose()
/// <returns>The position of the buffer after the last byte of the resulting sequence.</returns>
internal static int EncodeInBuffer(string str, bool isParameter, byte[] buffer, int position)
{
if (string.IsNullOrEmpty(str))
{
return position;
}

int charCount = str.Length;
int ellipses = isParameter ? "{...}\n".Length : "...\n".Length;

Expand Down Expand Up @@ -110,47 +116,6 @@ internal static int EncodeInBuffer(string str, bool isParameter, byte[] buffer,
return position;
}

internal void WriteEvent(string eventMessage, ReadOnlyCollection<object> payload)
{
try
{
var buffer = this.writeBuffer.Value;
if (buffer == null)
{
buffer = new byte[BUFFERSIZE];
this.writeBuffer.Value = buffer;
}

var pos = this.DateTimeGetBytes(DateTime.UtcNow, buffer, 0);
buffer[pos++] = (byte)':';
pos = EncodeInBuffer(eventMessage, false, buffer, pos);
if (payload != null)
{
// Not using foreach because it can cause allocations
for (int i = 0; i < payload.Count; ++i)
{
object obj = payload[i];
if (obj != null)
{
pos = EncodeInBuffer(obj.ToString(), true, buffer, pos);
}
else
{
pos = EncodeInBuffer("null", true, buffer, pos);
}
}
}

buffer[pos++] = (byte)'\n';
this.fileHandler.Write(buffer, pos - 0);
}
catch (Exception)
{
// Fail to allocate memory for buffer
// In this case, silently fail.
}
}

/// <summary>
/// Write the <c>datetime</c> formatted string into <c>bytes</c> byte-array starting at <c>byteIndex</c> position.
/// <para>
Expand All @@ -173,7 +138,7 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection<object> payload
/// <param name="bytes">Array of bytes to write.</param>
/// <param name="byteIndex">Starting index into bytes array.</param>
/// <returns>The number of bytes written.</returns>
internal int DateTimeGetBytes(DateTime datetime, byte[] bytes, int byteIndex)
internal static int DateTimeGetBytes(DateTime datetime, byte[] bytes, int byteIndex)
{
int num;
int pos = byteIndex;
Expand Down Expand Up @@ -256,6 +221,47 @@ internal int DateTimeGetBytes(DateTime datetime, byte[] bytes, int byteIndex)
return pos - byteIndex;
}

internal void WriteEvent(string eventMessage, ReadOnlyCollection<object> payload)
{
try
{
var buffer = this.writeBuffer.Value;
if (buffer == null)
{
buffer = new byte[BUFFERSIZE];
this.writeBuffer.Value = buffer;
}

var pos = DateTimeGetBytes(DateTime.UtcNow, buffer, 0);
buffer[pos++] = (byte)':';
pos = EncodeInBuffer(eventMessage, false, buffer, pos);
if (payload != null)
{
// Not using foreach because it can cause allocations
for (int i = 0; i < payload.Count; ++i)
{
object obj = payload[i];
if (obj != null)
{
pos = EncodeInBuffer(obj.ToString(), true, buffer, pos);
}
else
{
pos = EncodeInBuffer("null", true, buffer, pos);
}
}
}

buffer[pos++] = (byte)'\n';
this.fileHandler.Write(buffer, pos - 0);
}
catch (Exception)
{
// Fail to allocate memory for buffer
// In this case, silently fail.
}
}

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name.StartsWith(EventSourceNamePrefix, StringComparison.Ordinal))
Expand Down Expand Up @@ -310,9 +316,6 @@ protected virtual void Dispose(bool disposing)
}

this.disposedValue = true;

// Should call base.Dispose(disposing) here, but EventListener doesn't have Dispose(bool).
base.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class SelfDiagnosticsInitializer : IDisposable

// Long-living object that holds a refresher which checks whether the configuration file was updated
// every 10 seconds.
// private readonly SelfDiagnosticsConfigRefresher configRefresher;
private readonly SelfDiagnosticsConfigRefresher configRefresher;

static SelfDiagnosticsInitializer()
{
Expand All @@ -27,7 +27,7 @@ static SelfDiagnosticsInitializer()

private SelfDiagnosticsInitializer()
{
// this.configRefresher = new SelfDiagnosticsConfigRefresher();
this.configRefresher = new SelfDiagnosticsConfigRefresher();
}

/// <summary>
Expand All @@ -54,7 +54,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// this.configRefresher.Dispose();
this.configRefresher.Dispose();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog

## VNext

- [Enable the self diagnostics and fix a NullReferenceException bug](https://github.com/microsoft/ApplicationInsights-dotnet/pull/2302)

## Version 2.18.0-beta2
- Reduce technical debt: Use pattern matching
Expand Down