diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln
index 1e214bee3cb..94fc0021654 100644
--- a/OpenTelemetry.sln
+++ b/OpenTelemetry.sln
@@ -196,6 +196,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcService", "examples\GrpcService\Examples.GrpcService.csproj", "{DB942F5A-D571-4DEA-B1A7-B6BE0E24E6ED}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started", "docs\logs\getting-started\getting-started.csproj", "{B3F03725-23A0-4582-9526-F6A7E38F35CC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -378,6 +380,10 @@ Global
{DB942F5A-D571-4DEA-B1A7-B6BE0E24E6ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB942F5A-D571-4DEA-B1A7-B6BE0E24E6ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB942F5A-D571-4DEA-B1A7-B6BE0E24E6ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B3F03725-23A0-4582-9526-F6A7E38F35CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B3F03725-23A0-4582-9526-F6A7E38F35CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B3F03725-23A0-4582-9526-F6A7E38F35CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B3F03725-23A0-4582-9526-F6A7E38F35CC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -406,6 +412,7 @@ Global
{FCDCF532-A163-40DA-80B7-7530AA1182C4} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}
{B26BE278-C9DA-4067-A0EE-6A4227B3DC87} = {3862190B-E2C5-418E-AFDC-DB281FB5C705}
{DB942F5A-D571-4DEA-B1A7-B6BE0E24E6ED} = {E359BB2B-9AEC-497D-B321-7DF2450C3B8E}
+ {B3F03725-23A0-4582-9526-F6A7E38F35CC} = {3862190B-E2C5-418E-AFDC-DB281FB5C705}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}
diff --git a/build/Common.props b/build/Common.props
index 3a72e340d98..fbea8bc8cd9 100644
--- a/build/Common.props
+++ b/build/Common.props
@@ -31,6 +31,8 @@
[3.3.0]
[16.7.1]
[2.1.0,5.0)
+ [2.1.0,6.0)
+ [2.1.0,6.0)
[1.0.0,2.0)
[1.0.0,2.0)
[12.0.2,13.0)
diff --git a/docs/Directory.Build.props b/docs/Directory.Build.props
index 36cb1aa1b19..8ce176a76ef 100644
--- a/docs/Directory.Build.props
+++ b/docs/Directory.Build.props
@@ -11,6 +11,7 @@
Please sort alphabetically.
Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax.
-->
+ [5.0.0-rc.1.20451.14,6.0)
[0.4.0-beta.2,1.0)
[0.4.0-beta.2,1.0)
diff --git a/docs/logs/getting-started/Program.cs b/docs/logs/getting-started/Program.cs
new file mode 100644
index 00000000000..65b5142b2ff
--- /dev/null
+++ b/docs/logs/getting-started/Program.cs
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+using Microsoft.Extensions.Logging;
+
+public class Program
+{
+ public static void Main()
+ {
+ using var loggerFactory = LoggerFactory.Create(builder =>
+ {
+ builder.AddOpenTelemetry();
+ });
+ var logger = loggerFactory.CreateLogger();
+
+ logger.LogInformation("Hello, World!");
+ logger.LogInformation("Hello from {name} {price}.", "artichoke", 3.99);
+ }
+}
diff --git a/docs/logs/getting-started/README.md b/docs/logs/getting-started/README.md
new file mode 100644
index 00000000000..6941cf47115
--- /dev/null
+++ b/docs/logs/getting-started/README.md
@@ -0,0 +1,3 @@
+# Getting Started with OpenTelemetry .NET in 5 Minutes
+
+TBD
diff --git a/docs/logs/getting-started/getting-started.csproj b/docs/logs/getting-started/getting-started.csproj
new file mode 100644
index 00000000000..fed46f5b594
--- /dev/null
+++ b/docs/logs/getting-started/getting-started.csproj
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md
index 0575e5078d5..823e7c21b8f 100644
--- a/src/OpenTelemetry.Api/CHANGELOG.md
+++ b/src/OpenTelemetry.Api/CHANGELOG.md
@@ -2,6 +2,9 @@
## Unreleased
+* Added `ILogger`/`Microsoft.Extensions.Logging` integration
+ ([#1308](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1308))
+
## 0.6.0-beta.1
Released 2020-Sep-15
diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLogger.cs b/src/OpenTelemetry/Logs/OpenTelemetryLogger.cs
new file mode 100644
index 00000000000..1f3fd82f9ea
--- /dev/null
+++ b/src/OpenTelemetry/Logs/OpenTelemetryLogger.cs
@@ -0,0 +1,93 @@
+//
+// 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.
+//
+
+#if NETSTANDARD2_0
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Microsoft.Extensions.Logging;
+
+namespace OpenTelemetry.Logs
+{
+ internal class OpenTelemetryLogger : ILogger
+ {
+ private readonly string categoryName;
+
+ internal OpenTelemetryLogger(string categoryName, OpenTelemetryLoggerOptions options)
+ {
+ this.categoryName = categoryName ?? throw new ArgumentNullException(nameof(categoryName));
+
+ if (options == null)
+ {
+ throw new ArgumentNullException(nameof(options));
+ }
+ }
+
+ internal IExternalScopeProvider ScopeProvider { get; set; }
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter)
+ {
+ if (!this.IsEnabled(logLevel))
+ {
+ return;
+ }
+
+ var timestamp = DateTime.UtcNow;
+
+ if (state is IReadOnlyCollection> dict)
+ {
+ var isUnstructuredLog = dict.Count == 1;
+
+ // TODO: remove the console output after finished the plumbing work to log processors/exporters
+ if (isUnstructuredLog)
+ {
+ foreach (var entry in dict)
+ {
+ Console.WriteLine($"{this.categoryName}({logLevel}, Id={eventId}): {entry.Value}");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"{this.categoryName}({logLevel}, Id={eventId}):");
+ foreach (var entry in dict)
+ {
+ if (string.Equals(entry.Key, "{OriginalFormat}", StringComparison.Ordinal))
+ {
+ Console.WriteLine($" $format: {entry.Value}");
+ continue;
+ }
+
+ Console.WriteLine($" {entry.Key}: {entry.Value}");
+ }
+ }
+
+ if (exception != null)
+ {
+ Console.WriteLine($" $exception: {exception}");
+ }
+ }
+ }
+
+ public bool IsEnabled(LogLevel logLevel)
+ {
+ return logLevel != LogLevel.None;
+ }
+
+ public IDisposable BeginScope(TState state) => this.ScopeProvider?.Push(state) ?? null;
+ }
+}
+#endif
diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs
new file mode 100644
index 00000000000..f44baf424f2
--- /dev/null
+++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerOptions.cs
@@ -0,0 +1,26 @@
+//
+// 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.
+//
+
+#if NETSTANDARD2_0
+using Microsoft.Extensions.Logging;
+
+namespace OpenTelemetry.Logs
+{
+ public class OpenTelemetryLoggerOptions
+ {
+ }
+}
+#endif
diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
new file mode 100644
index 00000000000..66aae355095
--- /dev/null
+++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
@@ -0,0 +1,79 @@
+//
+// 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.
+//
+
+#if NETSTANDARD2_0
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace OpenTelemetry.Logs
+{
+ [ProviderAlias("OpenTelemetry")]
+ public class OpenTelemetryLoggerProvider : ILoggerProvider, ISupportExternalScope
+ {
+ private readonly IOptionsMonitor options;
+ private readonly IDictionary loggers;
+ private IExternalScopeProvider scopeProvider;
+
+ public OpenTelemetryLoggerProvider(IOptionsMonitor options)
+ {
+ this.options = options;
+ this.loggers = new Dictionary(StringComparer.Ordinal);
+ }
+
+ internal IExternalScopeProvider ScopeProvider
+ {
+ get
+ {
+ if (this.scopeProvider == null)
+ {
+ this.scopeProvider = new LoggerExternalScopeProvider();
+ }
+
+ return this.scopeProvider;
+ }
+ }
+
+ void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider)
+ {
+ // TODO: set existing loggers
+ this.scopeProvider = scopeProvider;
+ }
+
+ public ILogger CreateLogger(string categoryName)
+ {
+ lock (this.loggers)
+ {
+ ILogger logger;
+
+ if (this.loggers.TryGetValue(categoryName, out logger))
+ {
+ return logger;
+ }
+
+ logger = new OpenTelemetryLogger(categoryName, this.options.CurrentValue);
+ this.loggers.Add(categoryName, logger);
+ return logger;
+ }
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+}
+#endif
diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs
new file mode 100644
index 00000000000..bc44746b855
--- /dev/null
+++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggingExtensions.cs
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+
+#if NETSTANDARD2_0
+using System;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Configuration;
+using OpenTelemetry.Logs;
+
+namespace Microsoft.Extensions.Logging
+{
+ public static class OpenTelemetryLoggingExtensions
+ {
+ public static ILoggingBuilder AddOpenTelemetry(this ILoggingBuilder builder, Action configure = null)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ builder.AddConfiguration();
+ builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton());
+
+ if (configure != null)
+ {
+ builder.Services.Configure(configure);
+ }
+
+ return builder;
+ }
+ }
+}
+#endif
diff --git a/src/OpenTelemetry/OpenTelemetry.csproj b/src/OpenTelemetry/OpenTelemetry.csproj
index 7089e30f320..05f4a7c9bb5 100644
--- a/src/OpenTelemetry/OpenTelemetry.csproj
+++ b/src/OpenTelemetry/OpenTelemetry.csproj
@@ -18,6 +18,11 @@
+
+
+
+
+