Skip to content

Commit

Permalink
Logs: Add helper ctors & forceflush on OpenTelemetryLoggerProvider (#…
Browse files Browse the repository at this point in the history
…3364)

* Add helper ctors & forceflush on OpenTelemetryLoggerProvider.

* CHANGELOG update.

* Unit tests.

* Code review.

* Code review.

* Tweak.
  • Loading branch information
CodeBlanch authored Jun 16, 2022
1 parent 870eb92 commit 17e6d76
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
~OpenTelemetry.BaseExporter<T>.ParentProvider.get -> OpenTelemetry.BaseProvider
~OpenTelemetry.BaseExportProcessor<T>
~OpenTelemetry.BaseExportProcessor<T>.BaseExportProcessor(OpenTelemetry.BaseExporter<T> exporter) -> void
~OpenTelemetry.BaseProcessor<T>.ParentProvider.get -> OpenTelemetry.BaseProvider
OpenTelemetry.BaseProcessor<T>.ParentProvider.get -> OpenTelemetry.BaseProvider?
~OpenTelemetry.Batch<T>
~OpenTelemetry.Batch<T>.Batch(T[] items, int count) -> void
~OpenTelemetry.Batch<T>.Enumerator.Current.get -> T
Expand Down
3 changes: 3 additions & 0 deletions src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action<OpenTelemetry.Logs.OpenTelemetryLoggerOptions!>! configure) -> void
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
~OpenTelemetry.BaseExporter<T>.ParentProvider.get -> OpenTelemetry.BaseProvider
~OpenTelemetry.BaseExportProcessor<T>
~OpenTelemetry.BaseExportProcessor<T>.BaseExportProcessor(OpenTelemetry.BaseExporter<T> exporter) -> void
~OpenTelemetry.BaseProcessor<T>.ParentProvider.get -> OpenTelemetry.BaseProvider
OpenTelemetry.BaseProcessor<T>.ParentProvider.get -> OpenTelemetry.BaseProvider?
~OpenTelemetry.Batch<T>
~OpenTelemetry.Batch<T>.Batch(T[] items, int count) -> void
~OpenTelemetry.Batch<T>.Enumerator.Current.get -> T
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void
OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider(System.Action<OpenTelemetry.Logs.OpenTelemetryLoggerOptions!>! configure) -> void
19 changes: 17 additions & 2 deletions src/OpenTelemetry/BaseProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// limitations under the License.
// </copyright>

#nullable enable

using System;
using System.Threading;
using OpenTelemetry.Internal;
Expand All @@ -26,12 +28,21 @@ namespace OpenTelemetry
/// <typeparam name="T">The type of object to be processed.</typeparam>
public abstract class BaseProcessor<T> : IDisposable
{
private readonly string typeName;
private int shutdownCount;

/// <summary>
/// Initializes a new instance of the <see cref="BaseProcessor{T}"/> class.
/// </summary>
public BaseProcessor()
{
this.typeName = this.GetType().Name;
}

/// <summary>
/// Gets the parent <see cref="BaseProvider"/>.
/// </summary>
public BaseProvider ParentProvider { get; private set; }
public BaseProvider? ParentProvider { get; private set; }

/// <summary>
/// Called synchronously when a telemetry object is started.
Expand Down Expand Up @@ -86,7 +97,11 @@ public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite)

try
{
return this.OnForceFlush(timeoutMilliseconds);
bool result = this.OnForceFlush(timeoutMilliseconds);

OpenTelemetrySdkEventSource.Log.ProcessorForceFlushInvoked(this.typeName, result);

return result;
}
catch (Exception ex)
{
Expand Down
3 changes: 3 additions & 0 deletions src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* `CompositeProcessor` will now ensure `ParentProvider` is set on its children
([#3368](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3368))

* Added `ForceFlush` and helper ctors on `OpenTelemetryLoggerProvider`
([#3364](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3364))

## 1.3.0

Released 2022-Jun-03
Expand Down
6 changes: 6 additions & 0 deletions src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,12 @@ public void UnsupportedAttributeType(string type, string key)
this.WriteEvent(42, type.ToString(), key);
}

[Event(43, Message = "ForceFlush invoked for processor type '{0}' returned result '{1}'.", Level = EventLevel.Verbose)]
public void ProcessorForceFlushInvoked(string processorType, bool result)
{
this.WriteEvent(43, processorType, result);
}

#if DEBUG
public class OpenTelemetryEventListener : EventListener
{
Expand Down
49 changes: 49 additions & 0 deletions src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

#nullable enable

using System;
using System.Collections;
using System.Threading;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenTelemetry.Internal;
Expand Down Expand Up @@ -54,6 +56,23 @@ public OpenTelemetryLoggerProvider(IOptionsMonitor<OpenTelemetryLoggerOptions> o
{
}

/// <summary>
/// Initializes a new instance of the <see cref="OpenTelemetryLoggerProvider"/> class.
/// </summary>
/// <param name="configure"><see cref="OpenTelemetryLoggerOptions"/> configuration callback.</param>
public OpenTelemetryLoggerProvider(Action<OpenTelemetryLoggerOptions> configure)
: this(BuildOptions(configure ?? throw new ArgumentNullException(nameof(configure))))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="OpenTelemetryLoggerProvider"/> class.
/// </summary>
public OpenTelemetryLoggerProvider()
: this(BuildOptions(configure: null))
{
}

internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options)
{
Guard.ThrowIfNull(options);
Expand Down Expand Up @@ -112,6 +131,29 @@ public ILogger CreateLogger(string categoryName)
return logger;
}

/// <summary>
/// Flushes all the processors registered under <see
/// cref="OpenTelemetryLoggerProvider"/>, blocks the current thread
/// until flush completed, shutdown signaled or timed out.
/// </summary>
/// <param name="timeoutMilliseconds">
/// The number (non-negative) of milliseconds to wait, or
/// <c>Timeout.Infinite</c> to wait indefinitely.
/// </param>
/// <returns>
/// Returns <c>true</c> when force flush succeeded; otherwise, <c>false</c>.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when the <c>timeoutMilliseconds</c> is smaller than -1.
/// </exception>
/// <remarks>
/// This function guarantees thread-safety.
/// </remarks>
public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite)
{
return this.Processor?.ForceFlush(timeoutMilliseconds) ?? true;
}

internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor<LogRecord> processor)
{
Guard.ThrowIfNull(processor);
Expand Down Expand Up @@ -158,5 +200,12 @@ protected override void Dispose(bool disposing)

base.Dispose(disposing);
}

private static OpenTelemetryLoggerOptions BuildOptions(Action<OpenTelemetryLoggerOptions>? configure)
{
OpenTelemetryLoggerOptions options = new();
configure?.Invoke(options);
return options;
}
}
}
89 changes: 89 additions & 0 deletions test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggerProviderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// <copyright file="OpenTelemetryLoggerProviderTests.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Exporter;
using OpenTelemetry.Resources;
using Xunit;

namespace OpenTelemetry.Logs.Tests
{
public sealed class OpenTelemetryLoggerProviderTests
{
[Fact]
public void DefaultCtorTests()
{
OpenTelemetryLoggerOptions defaults = new();

using OpenTelemetryLoggerProvider provider = new();

Assert.Equal(defaults.IncludeScopes, provider.IncludeScopes);
Assert.Equal(defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage);
Assert.Equal(defaults.ParseStateValues, provider.ParseStateValues);
Assert.Null(provider.Processor);
Assert.NotNull(provider.Resource);
}

[Fact]
public void ConfigureCtorTests()
{
OpenTelemetryLoggerOptions defaults = new();

using OpenTelemetryLoggerProvider provider = new(options =>
{
options.IncludeScopes = !defaults.IncludeScopes;
options.IncludeFormattedMessage = !defaults.IncludeFormattedMessage;
options.ParseStateValues = !defaults.ParseStateValues;

options.SetResourceBuilder(ResourceBuilder
.CreateEmpty()
.AddAttributes(new[] { new KeyValuePair<string, object>("key1", "value1") }));

options.AddInMemoryExporter(new List<LogRecord>());
});

Assert.Equal(!defaults.IncludeScopes, provider.IncludeScopes);
Assert.Equal(!defaults.IncludeFormattedMessage, provider.IncludeFormattedMessage);
Assert.Equal(!defaults.ParseStateValues, provider.ParseStateValues);
Assert.NotNull(provider.Processor);
Assert.NotNull(provider.Resource);
Assert.Contains(provider.Resource.Attributes, value => value.Key == "key1" && (string)value.Value == "value1");
}

[Fact]
public void ForceFlushTest()
{
using OpenTelemetryLoggerProvider provider = new();

Assert.True(provider.ForceFlush());

List<LogRecord> exportedItems = new();

provider.AddProcessor(new BatchLogRecordExportProcessor(new InMemoryExporter<LogRecord>(exportedItems)));

var logger = provider.CreateLogger("TestLogger");

logger.LogInformation("hello world");

Assert.Empty(exportedItems);

Assert.True(provider.ForceFlush());

Assert.Single(exportedItems);
}
}
}

0 comments on commit 17e6d76

Please sign in to comment.