Skip to content

Commit

Permalink
Merge branch 'main' into Optimize-GetOrAdd
Browse files Browse the repository at this point in the history
  • Loading branch information
cijothomas authored Jan 29, 2021
2 parents 65f72c2 + 6fe93f8 commit 0505585
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 2 deletions.
108 changes: 106 additions & 2 deletions src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection<object> payload
this.writeBuffer.Value = buffer;
}

var timestamp = DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture);
var pos = Encoding.UTF8.GetBytes(timestamp, 0, timestamp.Length, buffer, 0);
var pos = this.DateTimeGetBytes(DateTime.UtcNow, buffer, 0);
buffer[pos++] = (byte)':';
pos = EncodeInBuffer(eventMessage, false, buffer, pos);
if (payload != null)
Expand Down Expand Up @@ -172,6 +171,111 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection<object> payload
}
}

/// <summary>
/// Write the <c>datetime</c> formatted string into <c>bytes</c> byte-array starting at <c>byteIndex</c> position.
/// <para>
/// [DateTimeKind.Utc]
/// format: yyyy - MM - dd T HH : mm : ss . fffffff Z (i.e. 2020-12-09T10:20:50.4659412Z).
/// </para>
/// <para>
/// [DateTimeKind.Local]
/// format: yyyy - MM - dd T HH : mm : ss . fffffff +|- HH : mm (i.e. 2020-12-09T10:20:50.4659412-08:00).
/// </para>
/// <para>
/// [DateTimeKind.Unspecified]
/// format: yyyy - MM - dd T HH : mm : ss . fffffff (i.e. 2020-12-09T10:20:50.4659412).
/// </para>
/// </summary>
/// <remarks>
/// The bytes array must be large enough to write 27-33 charaters from the byteIndex starting position.
/// </remarks>
/// <param name="datetime">DateTime.</param>
/// <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)
{
int num;
int pos = byteIndex;

num = datetime.Year;
bytes[pos++] = (byte)('0' + ((num / 1000) % 10));
bytes[pos++] = (byte)('0' + ((num / 100) % 10));
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)'-';

num = datetime.Month;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)'-';

num = datetime.Day;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)'T';

num = datetime.Hour;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)':';

num = datetime.Minute;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)':';

num = datetime.Second;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)'.';

num = (int)(Math.Round(datetime.TimeOfDay.TotalMilliseconds * 10000) % 10000000);
bytes[pos++] = (byte)('0' + ((num / 1000000) % 10));
bytes[pos++] = (byte)('0' + ((num / 100000) % 10));
bytes[pos++] = (byte)('0' + ((num / 10000) % 10));
bytes[pos++] = (byte)('0' + ((num / 1000) % 10));
bytes[pos++] = (byte)('0' + ((num / 100) % 10));
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

switch (datetime.Kind)
{
case DateTimeKind.Utc:
bytes[pos++] = (byte)'Z';
break;

case DateTimeKind.Local:
TimeSpan ts = TimeZoneInfo.Local.GetUtcOffset(datetime);

bytes[pos++] = (byte)(ts.Hours >= 0 ? '+' : '-');

num = Math.Abs(ts.Hours);
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));

bytes[pos++] = (byte)':';

num = ts.Minutes;
bytes[pos++] = (byte)('0' + ((num / 10) % 10));
bytes[pos++] = (byte)('0' + (num % 10));
break;

case DateTimeKind.Unspecified:
default:
// Skip
break;
}

return pos - byteIndex;
}

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name.StartsWith(EventSourceNamePrefix, StringComparison.Ordinal))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,45 @@ public void SelfDiagnosticsEventListener_WriteEvent()
AssertFileOutput(LOGFILEPATH, eventMessage);
}

[Fact]
[Trait("Platform", "Any")]
public void SelfDiagnosticsEventListener_DateTimeGetBytes()
{
var configRefresherMock = new Mock<SelfDiagnosticsConfigRefresher>();
var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object);

// 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.UtcNow,
DateTime.Now,
};

// Expect to match output string from DateTime.ToString("O")
string[] expected = new string[datetimes.Length];
for (int i = 0; i < datetimes.Length; i++)
{
expected[i] = datetimes[i].ToString("O");
}

byte[] buffer = new byte[40 * datetimes.Length];
int pos = 0;

// Get string after DateTimeGetBytes() write into a buffer
string[] results = new string[datetimes.Length];
for (int i = 0; i < datetimes.Length; i++)
{
int len = listener.DateTimeGetBytes(datetimes[i], buffer, pos);
results[i] = Encoding.Default.GetString(buffer, pos, len);
pos += len;
}

Assert.Equal(expected, results);
}

[Fact]
[Trait("Platform", "Any")]
public void SelfDiagnosticsEventListener_EmitEvent_OmitAsConfigured()
Expand Down

0 comments on commit 0505585

Please sign in to comment.