From 7fde48fd2278a135105cb061b857d213a28f0fb2 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 20 Dec 2022 14:30:08 -0300 Subject: [PATCH 01/18] Initial bits for OpenTelemetry --- dotnet/DotNetStandardClasses.sln | 4 ++ .../src/dotnetcore/GxClasses/GxClasses.csproj | 1 + .../OpenTelemetry/OpenTelemetryService.cs | 59 ++++++++++++++++++ .../dotnetcore/GxNetCoreStartup/Startup.cs | 11 +++- .../AWSOtel/AWSOtelAspNet.csproj | 25 ++++++++ .../AWSOtel/AWSOtelAspNetProvider.cs | 29 +++++++++ .../GXOpenTelemetry/GXOpenTelemetry.csproj | 9 +++ .../GXOpenTelemetry/OpenTelemetryService.cs | 62 +++++++++++++++++++ .../Configuration/LogConfiguration.cs | 45 ++++++++++++++ .../GxClasses/Diagnostics/Log.cs | 6 +- 10 files changed, 245 insertions(+), 6 deletions(-) create mode 100644 dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs create mode 100644 dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj create mode 100644 dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs create mode 100644 dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 9acaf7c71..6a4e4647c 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -222,6 +222,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetRedisTest", "test\Dot EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCoreWebUnitTest", "test\DotNetCoreWebUnitTest\DotNetCoreWebUnitTest.csproj", "{531863CA-93A0-42AA-AB5C-FA0E672C03B8}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opentelemetry", "opentelemetry", "{BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSOtelAspNet", "src\dotnetcore\Providers\OpenTelemetry\AWSOtel\AWSOtelAspNet.csproj", "{6BAEDA8C-EFB6-43FF-85A5-FCD323C59323}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index 81ccb82fc..4eb02c026 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -17,6 +17,7 @@ + diff --git a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs new file mode 100644 index 000000000..047196960 --- /dev/null +++ b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GxClasses.Helpers; +using log4net; + +namespace GeneXus.Services.OpenTelemetry +{ + internal class OpenTelemetryService + { + private static readonly ILog log = log4net.LogManager.GetLogger(typeof(OpenTelemetryService)); + + public static string OPENTELEMETRY_SERVICE = "OpenTelemetry"; + + public interface IOpenTelemetryProvider + { + bool InstrumentApplication(); + } + + private static IOpenTelemetryProvider GetOpenTelemetryProvider() + { + IOpenTelemetryProvider otelProvider = null; + GXService providerService = GXServices.Instance?.Get(OPENTELEMETRY_SERVICE); + + if (providerService != null) + { + try + { + GXLogging.Debug(log, "Loading OpenTelemetry provider:", providerService.ClassName); +#if !NETCORE + Type type = Type.GetType(providerService.ClassName, true, true); +#else + Type type = AssemblyLoader.GetType(providerService.ClassName); +#endif + otelProvider = (IOpenTelemetryProvider)Activator.CreateInstance(type); + } + catch (Exception e) + { + GXLogging.Error(log, "Couldn´t create OpenTelemetry provider.", e.Message, e); + throw e; + } + } + return otelProvider; + } + + internal static void Setup() + { + IOpenTelemetryProvider provider = OpenTelemetryService.GetOpenTelemetryProvider(); + if (provider == null) + { + provider.InstrumentApplication(); + } + } + } + + +} diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs index 01fff17b2..3250a5884 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs @@ -7,6 +7,7 @@ using GeneXus.Http; using GeneXus.HttpHandlerFactory; using GeneXus.Services; +using GeneXus.Services.OpenTelemetry; using GeneXus.Utils; using GxClasses.Web.Middleware; using log4net; @@ -265,7 +266,8 @@ private void ConfigureSessionService(IServiceCollection services, ISessionServic public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory) { string baseVirtualPath = string.IsNullOrEmpty(VirtualPath) ? VirtualPath : $"/{VirtualPath}"; - + LogConfiguration.SetupLog4Net(); + ConfigureOpenTelemetry(); var provider = new FileExtensionContentTypeProvider(); //mappings provider.Mappings[".json"] = "application/json"; @@ -434,7 +436,12 @@ private void ConfigureSwaggerUI(IApplicationBuilder app, string baseVirtualPath) Console.Error.WriteLine("Errpr loading SwaggerUI " + ex.Message); } } - + + private void ConfigureOpenTelemetry() + { + OpenTelemetryService.Setup(); + } + private void AddRewrite(IApplicationBuilder app, string rewriteFile, string baseURL) { string rules = File.ReadAllText(rewriteFile); diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj new file mode 100644 index 000000000..f411c0bc3 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + TRACE;DEBUG;NETCORE + Properties + false + GeneXus.OpenTelemetry.AWS.AspNet + AWS Distro for OpenTelemetry for .NET + GeneXus.OpenTelemetry.AWS.AspNet + + + + + + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs new file mode 100644 index 000000000..dc6083ed8 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs @@ -0,0 +1,29 @@ +using System; +using GeneXus.Services; +using OpenTelemetry; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Trace; + +namespace GeneXus.OpenTelemetry.AWS +{ + public class AWSOtelAspNetProvider : IOpenTelemetryProvider + { + public bool InstrumentApplication() + { + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() // for generating AWS X-Ray compliant trace IDs + .AddOtlpExporter(options => + { + options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + }) + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddAWSInstrumentation() + .Build(); + + Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); + + return true; + } + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj new file mode 100644 index 000000000..132c02c59 --- /dev/null +++ b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs new file mode 100644 index 000000000..5f77a0ccb --- /dev/null +++ b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs @@ -0,0 +1,62 @@ +namespace GXOpenTelemetry +{ + public class OpenTelemetryService + { + + public static Instance + { + get + { + if (instance == null) + { + lock (syncRoot) + { + if (instance == null) + { + + GXServices services = GXServices.Instance; + if (services != null) + { + GXService providerService = services.Get(GXServices.CACHE_SERVICE); + if (providerService != null) + { + GXLogging.Debug(log, "Loading CACHE_PROVIDER: ", providerService.ClassName); + try + { +#if NETCORE + Type type = AssemblyLoader.GetType(providerService.ClassName); +#else + Type type = Type.GetType(providerService.ClassName, true, true); +#endif + instance = (ICacheService)Activator.CreateInstance(type); + if (providerService.Properties.ContainsKey(FORCE_HIGHEST_TIME_TO_LIVE)) + { + int ttl; + if (Int32.TryParse(providerService.Properties.Get(FORCE_HIGHEST_TIME_TO_LIVE), out ttl) && ttl == 1) + { + forceHighestTimetoLive = true; + } + } + } + catch (Exception e) + { + GXLogging.Error(log, "Couldn't create CACHE_PROVIDER as ICacheService: ", providerService.ClassName, e); + throw e; + } + } + } + if (instance == null) + { + GXLogging.Debug(log, "Loading Default CACHE_PROVIDER InMemoryCache"); + instance = new InProcessCache(); + } + } + } + } + + return instance; + } + } + + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs new file mode 100644 index 000000000..1d458cc3d --- /dev/null +++ b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs @@ -0,0 +1,45 @@ +using System; +using log4net; +using log4net.Core; +using log4net.Repository; +using log4net.Repository.Hierarchy; + +namespace GeneXus.Configuration +{ + internal static class LogConfiguration + { + public const string USER_LOG_TOPIC = "GeneXusUserLog"; + private const string LOGLEVEL_ENVVAR = "GX_LOG_LEVEL"; + private const string USERLOGLEVEL_ENVVAR = "GX_LOG_LEVEL_USER"; + + public static void SetupLog4Net() + { + SetupLog4NetFromEnvironmentVariables(); + } + + private static void SetupLog4NetFromEnvironmentVariables() + { + System.Diagnostics.Debugger.Launch(); + string logLevel = Environment.GetEnvironmentVariable(LOGLEVEL_ENVVAR); + + if (!string.IsNullOrEmpty(logLevel)) + { + Hierarchy h = (Hierarchy)LogManager.GetRepository(); + h.Root.Level = h.LevelMap[logLevel.ToUpper()]; + } + + string userLogLevel = Environment.GetEnvironmentVariable(USERLOGLEVEL_ENVVAR); + + if (!string.IsNullOrEmpty(userLogLevel)) + { + ILoggerRepository[] repositories = LogManager.GetAllRepositories(); + foreach (ILoggerRepository repository in repositories) + { + Hierarchy hier = (Hierarchy)repository; + ILogger logger = hier.GetLogger(USER_LOG_TOPIC); + ((Logger)logger).Level = hier.LevelMap[userLogLevel]; + } + } + } + } +} diff --git a/dotnet/src/dotnetframework/GxClasses/Diagnostics/Log.cs b/dotnet/src/dotnetframework/GxClasses/Diagnostics/Log.cs index 02f0bfe0a..17ede87d5 100644 --- a/dotnet/src/dotnetframework/GxClasses/Diagnostics/Log.cs +++ b/dotnet/src/dotnetframework/GxClasses/Diagnostics/Log.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using GeneXus.Attributes; +using GeneXus.Configuration; using log4net; namespace GeneXus.Diagnostics @@ -25,7 +23,7 @@ private enum LogLevel #else static readonly string defaultRepository = LogManager.GetRepository().Name; #endif - public static string defaultUserLogNamespace = Configuration.Config.GetValueOf("USER_LOG_NAMESPACE", "GeneXusUserLog"); + public static string defaultUserLogNamespace = Configuration.Config.GetValueOf("USER_LOG_NAMESPACE", LogConfiguration.USER_LOG_TOPIC); static readonly ILog globalLog = LogManager.GetLogger(defaultRepository, defaultUserLogNamespace); From 9a2fe58aaa4761de0ee11c655b8aceb598db19cc Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 20 Dec 2022 16:15:16 -0300 Subject: [PATCH 02/18] Add Lightstep Observability Provider --- dotnet/DotNetStandardClasses.sln | 39 +++++++++----- .../src/dotnetcore/GxClasses/GxClasses.csproj | 4 +- .../OpenTelemetry/OpenTelemetryService.cs | 29 ++++++----- .../dotnetcore/GxNetCoreStartup/Startup.cs | 26 +++++----- .../AWSOtel/AWSOtelAspNetProvider.cs | 29 ----------- .../AWSOtelAspNetProvider.cs | 30 +++++++++++ .../GeneXus.OpenTelemetry.AWS.AspNet.csproj} | 12 ++--- ...eXus.OpenTelemetry.Lightstep.AspNet.csproj | 25 +++++++++ .../LightstepProvider.cs | 52 +++++++++++++++++++ 9 files changed, 171 insertions(+), 75 deletions(-) delete mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs rename dotnet/src/dotnetcore/Providers/OpenTelemetry/{AWSOtel/AWSOtelAspNet.csproj => OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj} (82%) create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 6a4e4647c..3cddcb3ad 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -212,9 +212,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXAmazonSQS", "src\dotnetco EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "apiattractions", "src\extensions\Azure\test\apiattractions\apiattractions.csproj", "{E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXMessageBroker", "src\dotnetcore\Providers\Messaging\GXMessageBroker\GXMessageBroker.csproj", "{3B1B5706-E896-4CEB-A551-E30226303BDB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXMessageBroker", "src\dotnetcore\Providers\Messaging\GXMessageBroker\GXMessageBroker.csproj", "{3B1B5706-E896-4CEB-A551-E30226303BDB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GXAzureServiceBus", "src\dotnetcore\Providers\Messaging\GXAzureServiceBus\GXAzureServiceBus.csproj", "{F8ABEA82-F823-4E9C-96FA-26AF24C932E0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GXAzureServiceBus", "src\dotnetcore\Providers\Messaging\GXAzureServiceBus\GXAzureServiceBus.csproj", "{F8ABEA82-F823-4E9C-96FA-26AF24C932E0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectHealthTest", "test\ProjectHealthTest\ProjectHealthTest.csproj", "{65048104-212A-4819-AECF-89CA9C08C83F}" EndProject @@ -224,7 +224,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCoreWebUnitTest", "te EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opentelemetry", "opentelemetry", "{BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSOtelAspNet", "src\dotnetcore\Providers\OpenTelemetry\AWSOtel\AWSOtelAspNet.csproj", "{6BAEDA8C-EFB6-43FF-85A5-FCD323C59323}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneXus.OpenTelemetry.Lightstep.AspNet", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetryLightStep\GeneXus.OpenTelemetry.Lightstep.AspNet.csproj", "{27D54041-BDD5-428E-8CA6-C96D519F5451}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneXus.OpenTelemetry.AWS.AspNet", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetryAWSOtel\GeneXus.OpenTelemetry.AWS.AspNet.csproj", "{B5A9DEA7-67EC-49E4-924E-4729C34286EC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -524,14 +526,6 @@ Global {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Debug|Any CPU.Build.0 = Debug|Any CPU {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Release|Any CPU.ActiveCfg = Release|Any CPU {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3}.Release|Any CPU.Build.0 = Release|Any CPU - {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.Build.0 = Release|Any CPU - {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {48430E50-043A-47A2-8278-B86A4420758A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {48430E50-043A-47A2-8278-B86A4420758A}.Release|Any CPU.Build.0 = Release|Any CPU {3B1B5706-E896-4CEB-A551-E30226303BDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3B1B5706-E896-4CEB-A551-E30226303BDB}.Debug|Any CPU.Build.0 = Debug|Any CPU {3B1B5706-E896-4CEB-A551-E30226303BDB}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -540,10 +534,26 @@ Global {F8ABEA82-F823-4E9C-96FA-26AF24C932E0}.Debug|Any CPU.Build.0 = Debug|Any CPU {F8ABEA82-F823-4E9C-96FA-26AF24C932E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {F8ABEA82-F823-4E9C-96FA-26AF24C932E0}.Release|Any CPU.Build.0 = Release|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65048104-212A-4819-AECF-89CA9C08C83F}.Release|Any CPU.Build.0 = Release|Any CPU + {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48430E50-043A-47A2-8278-B86A4420758A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48430E50-043A-47A2-8278-B86A4420758A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48430E50-043A-47A2-8278-B86A4420758A}.Release|Any CPU.Build.0 = Release|Any CPU {531863CA-93A0-42AA-AB5C-FA0E672C03B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {531863CA-93A0-42AA-AB5C-FA0E672C03B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {531863CA-93A0-42AA-AB5C-FA0E672C03B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {531863CA-93A0-42AA-AB5C-FA0E672C03B8}.Release|Any CPU.Build.0 = Release|Any CPU + {27D54041-BDD5-428E-8CA6-C96D519F5451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27D54041-BDD5-428E-8CA6-C96D519F5451}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27D54041-BDD5-428E-8CA6-C96D519F5451}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27D54041-BDD5-428E-8CA6-C96D519F5451}.Release|Any CPU.Build.0 = Release|Any CPU + {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -646,11 +656,14 @@ Global {DCEC0B38-93B6-4003-81E6-9FBC2BB4F163} = {7BA5A2CE-7992-4F87-9D84-91AE4D046F5A} {F8BA0D65-267D-491F-BFAB-33F5E5B61AD7} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} {E85FDB0F-FA81-4CDD-8BF3-865269CE2DB3} = {7BA5A2CE-7992-4F87-9D84-91AE4D046F5A} - {65048104-212A-4819-AECF-89CA9C08C83F} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} - {48430E50-043A-47A2-8278-B86A4420758A} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {3B1B5706-E896-4CEB-A551-E30226303BDB} = {4C43F2DA-59E5-46F5-B691-195449498555} {F8ABEA82-F823-4E9C-96FA-26AF24C932E0} = {30159B0F-BE61-4DB7-AC02-02851426BE4B} + {65048104-212A-4819-AECF-89CA9C08C83F} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} + {48430E50-043A-47A2-8278-B86A4420758A} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} {531863CA-93A0-42AA-AB5C-FA0E672C03B8} = {1D6F1776-FF4B-46C2-9B3D-BC46CCF049DC} + {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} + {27D54041-BDD5-428E-8CA6-C96D519F5451} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} + {B5A9DEA7-67EC-49E4-924E-4729C34286EC} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index 4eb02c026..df71a75fb 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -17,7 +17,7 @@ - + @@ -161,6 +161,8 @@ + + diff --git a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs index 047196960..faecfac6c 100644 --- a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs +++ b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs @@ -8,17 +8,16 @@ namespace GeneXus.Services.OpenTelemetry { - internal class OpenTelemetryService + public interface IOpenTelemetryProvider { - private static readonly ILog log = log4net.LogManager.GetLogger(typeof(OpenTelemetryService)); - - public static string OPENTELEMETRY_SERVICE = "OpenTelemetry"; - - public interface IOpenTelemetryProvider - { - bool InstrumentApplication(); - } + bool InstrumentAspNetCoreApplication(Microsoft.Extensions.DependencyInjection.IServiceCollection services); + } + internal static class OpenTelemetryService + { + private static readonly ILog log = log4net.LogManager.GetLogger(typeof(OpenTelemetryService)); + private static string OPENTELEMETRY_SERVICE = "OpenTelemetry"; + private static IOpenTelemetryProvider GetOpenTelemetryProvider() { IOpenTelemetryProvider otelProvider = null; @@ -45,12 +44,16 @@ private static IOpenTelemetryProvider GetOpenTelemetryProvider() return otelProvider; } - internal static void Setup() + internal static void Setup(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - IOpenTelemetryProvider provider = OpenTelemetryService.GetOpenTelemetryProvider(); - if (provider == null) + IOpenTelemetryProvider provider = GetOpenTelemetryProvider(); + if (provider != null) { - provider.InstrumentApplication(); + bool started = provider.InstrumentAspNetCoreApplication(services); + if (started) + { + log.Debug("OpenTelemetry instrumentation started"); + } } } } diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs index 3250a5884..13c73fe89 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs @@ -28,6 +28,10 @@ using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; using StackExchange.Redis; +using OpenTelemetry; +using OpenTelemetry.Trace; +using OpenTelemetry.Resources; + namespace GeneXus.Application { @@ -63,7 +67,7 @@ public static void Main(string[] args) Console.Error.WriteLine("ERROR:"); Console.Error.WriteLine("Web Host terminated unexpectedly: {0}", e.Message); Console.Read(); - } + } } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) @@ -78,7 +82,7 @@ public static IWebHost BuildWebHostPort(string[] args, string port) static IWebHost BuildWebHostPort(string[] args, string port, string schema) { return WebHost.CreateDefaultBuilder(args) - .ConfigureLogging(logging => logging.AddConsole()) + .ConfigureLogging(logging => logging.AddConsole()) .UseUrls($"{schema}://*:{port}") .UseStartup() .Build(); @@ -88,7 +92,7 @@ static IWebHost BuildWebHostPort(string[] args, string port, string schema) public static class GXHandlerExtensions { public static IApplicationBuilder UseGXHandlerFactory(this IApplicationBuilder builder, string basePath) - { + { return builder.UseMiddleware(basePath); } public static IApplicationBuilder MapWebSocketManager(this IApplicationBuilder app, string basePath) @@ -136,6 +140,8 @@ public Startup(IConfiguration configuration, IHostingEnvironment env) } public void ConfigureServices(IServiceCollection services) { + OpenTelemetryService.Setup(services); + services.AddMvc(option => option.EnableEndpointRouting = false); services.Configure(options => { @@ -147,7 +153,7 @@ public void ConfigureServices(IServiceCollection services) options.AllowSynchronousIO = true; }); services.AddDistributedMemoryCache(); - + services.Configure(options => { if (Config.GetValueOf("MaxFileUploadSize", out string MaxFileUploadSizeStr) && long.TryParse(MaxFileUploadSizeStr, out long MaxFileUploadSize)) @@ -264,10 +270,9 @@ private void ConfigureSessionService(IServiceCollection services, ISessionServic } } public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory) - { + { string baseVirtualPath = string.IsNullOrEmpty(VirtualPath) ? VirtualPath : $"/{VirtualPath}"; - LogConfiguration.SetupLog4Net(); - ConfigureOpenTelemetry(); + LogConfiguration.SetupLog4Net(); var provider = new FileExtensionContentTypeProvider(); //mappings provider.Mappings[".json"] = "application/json"; @@ -435,12 +440,7 @@ private void ConfigureSwaggerUI(IApplicationBuilder app, string baseVirtualPath) { Console.Error.WriteLine("Errpr loading SwaggerUI " + ex.Message); } - } - - private void ConfigureOpenTelemetry() - { - OpenTelemetryService.Setup(); - } + } private void AddRewrite(IApplicationBuilder app, string rewriteFile, string baseURL) { diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs deleted file mode 100644 index dc6083ed8..000000000 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNetProvider.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using GeneXus.Services; -using OpenTelemetry; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; -using OpenTelemetry.Trace; - -namespace GeneXus.OpenTelemetry.AWS -{ - public class AWSOtelAspNetProvider : IOpenTelemetryProvider - { - public bool InstrumentApplication() - { - TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddXRayTraceId() // for generating AWS X-Ray compliant trace IDs - .AddOtlpExporter(options => - { - options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); - }) - .AddAspNetCoreInstrumentation() - .AddHttpClientInstrumentation() - .AddAWSInstrumentation() - .Build(); - - Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); - - return true; - } - } -} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs new file mode 100644 index 000000000..0cd0b121f --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs @@ -0,0 +1,30 @@ +using System; +using GeneXus.Services.OpenTelemetry; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry; +using OpenTelemetry.Trace; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; + +namespace GeneXus.Otel.AWS +{ + public class AWSOtelAspNetProvider : IOpenTelemetryProvider + { + public bool InstrumentAspNetCoreApplication(IServiceCollection _) + { + Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() // for generating AWS X-Ray compliant trace IDs + .AddOtlpExporter(options => + { + options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + }) + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddAWSInstrumentation() + .Build(); + + Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); + + return true; + } + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj similarity index 82% rename from dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj rename to dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index f411c0bc3..ca25b9ae6 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/AWSOtel/AWSOtelAspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -11,11 +11,11 @@ - - - - - + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj new file mode 100644 index 000000000..63f6bc8e1 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + TRACE;DEBUG;NETCORE + Properties + false + GeneXus.OpenTelemetry.Lightstep.AspNet + Lightstep OpenTelemetry for .NET + GeneXus.OpenTelemetry.Lightstep.AspNet + + + + + + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs new file mode 100644 index 000000000..d761ce250 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -0,0 +1,52 @@ + +using System; +using GeneXus.Services.OpenTelemetry; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry; +using OpenTelemetry.Trace; +using OpenTelemetry.Resources; +using log4net; + +namespace GeneXus.OpenTelemetry.Lightstep +{ + + public class LightStepOpenTelemetry : IOpenTelemetryProvider + { + private static readonly ILog log = LogManager.GetLogger(typeof(LightStepOpenTelemetry)); + private const string LIGHTSTEP_INGREST_URL = "https://ingest.lightstep.com:443"; + private const string LIGHTSTEP_ACCESS_TOKEN = "LS_ACCESS_TOKEN"; + public bool InstrumentAspNetCoreApplication(IServiceCollection services) + { + //OTEL_SERVICE_NAME + string serviceName = "GXServiceName"; + string serviceVersion = "1.0.0"; + //TODO: Read dinamically. + + string lightstepToken = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); + + if (string.IsNullOrEmpty(lightstepToken)) + { + log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'LS_ACCESS_TOKEN' Environment Variable"); + return false; + } + + services.AddOpenTelemetryTracing(tracerProviderBuilder => + { + tracerProviderBuilder + .AddOtlpExporter(opt => + { + opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); + opt.Headers = $"lightstep-access-token=${lightstepToken}"; + }) + .AddSource(serviceName) + .SetResourceBuilder( + ResourceBuilder.CreateDefault() + .AddService(serviceName: serviceName, serviceVersion: serviceVersion)) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation(); + }); + + return true; + } + } +} From c533910471cbe14c2e0ed138632d76716878fa22 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 20 Dec 2022 16:18:04 -0300 Subject: [PATCH 03/18] Remove unused packages --- dotnet/src/dotnetcore/GxClasses/GxClasses.csproj | 1 - .../GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs | 4 ---- dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs | 3 --- 3 files changed, 8 deletions(-) diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index df71a75fb..96f92e7ed 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -162,7 +162,6 @@ - diff --git a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs index faecfac6c..e3492ed03 100644 --- a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs +++ b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using GxClasses.Helpers; using log4net; diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs index 13c73fe89..ca0494356 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs @@ -28,9 +28,6 @@ using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; using StackExchange.Redis; -using OpenTelemetry; -using OpenTelemetry.Trace; -using OpenTelemetry.Resources; namespace GeneXus.Application From b0528579237cd35a1063630c39b1556f404095cf Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 15:57:44 -0300 Subject: [PATCH 04/18] Initial bits for OpenTelemetry --- .../src/dotnetcore/GxClasses/GxClasses.csproj | 1 - .../OpenTelemetry/OpenTelemetryService.cs | 10 +- .../GxClasses/Services/ServiceSettings.cs | 94 +++++++++++++++++++ ...elAspNetProvider.cs => AWSOtelProvider.cs} | 25 ++++- .../GeneXus.OpenTelemetry.AWS.AspNet.csproj | 12 ++- ...eXus.OpenTelemetry.Lightstep.AspNet.csproj | 20 ++-- .../LightstepProvider.cs | 62 +++++++++--- .../Configuration/LogConfiguration.cs | 3 +- .../GxClasses/Core/GXApplication.cs | 2 +- 9 files changed, 190 insertions(+), 39 deletions(-) create mode 100644 dotnet/src/dotnetcore/GxClasses/Services/ServiceSettings.cs rename dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/{AWSOtelAspNetProvider.cs => AWSOtelProvider.cs} (56%) diff --git a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj index 96f92e7ed..8158da4be 100644 --- a/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj +++ b/dotnet/src/dotnetcore/GxClasses/GxClasses.csproj @@ -161,7 +161,6 @@ - diff --git a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs index e3492ed03..f8936d606 100644 --- a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs +++ b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs @@ -12,7 +12,7 @@ public interface IOpenTelemetryProvider internal static class OpenTelemetryService { private static readonly ILog log = log4net.LogManager.GetLogger(typeof(OpenTelemetryService)); - private static string OPENTELEMETRY_SERVICE = "OpenTelemetry"; + private static string OPENTELEMETRY_SERVICE = "Observability"; private static IOpenTelemetryProvider GetOpenTelemetryProvider() { @@ -20,7 +20,7 @@ private static IOpenTelemetryProvider GetOpenTelemetryProvider() GXService providerService = GXServices.Instance?.Get(OPENTELEMETRY_SERVICE); if (providerService != null) - { + { try { GXLogging.Debug(log, "Loading OpenTelemetry provider:", providerService.ClassName); @@ -29,7 +29,7 @@ private static IOpenTelemetryProvider GetOpenTelemetryProvider() #else Type type = AssemblyLoader.GetType(providerService.ClassName); #endif - otelProvider = (IOpenTelemetryProvider)Activator.CreateInstance(type); + otelProvider = (IOpenTelemetryProvider)Activator.CreateInstance(type, new object[] { providerService }); } catch (Exception e) { @@ -41,14 +41,14 @@ private static IOpenTelemetryProvider GetOpenTelemetryProvider() } internal static void Setup(Microsoft.Extensions.DependencyInjection.IServiceCollection services) - { + { IOpenTelemetryProvider provider = GetOpenTelemetryProvider(); if (provider != null) { bool started = provider.InstrumentAspNetCoreApplication(services); if (started) { - log.Debug("OpenTelemetry instrumentation started"); + log.Info("OpenTelemetry instrumentation started"); } } } diff --git a/dotnet/src/dotnetcore/GxClasses/Services/ServiceSettings.cs b/dotnet/src/dotnetcore/GxClasses/Services/ServiceSettings.cs new file mode 100644 index 000000000..2249548f0 --- /dev/null +++ b/dotnet/src/dotnetcore/GxClasses/Services/ServiceSettings.cs @@ -0,0 +1,94 @@ +using System; +using GeneXus.Encryption; +using log4net; + +namespace GeneXus.Services.Common +{ + public class ServiceSettingsReader + { + static readonly ILog logger = log4net.LogManager.GetLogger(typeof(ServiceSettingsReader)); + + internal GXService service; + public string serviceNameResolver { get; } + public string name { get; } + + public ServiceSettingsReader(string serviceNameResolver, string name, GXService gXService) + { + this.serviceNameResolver = serviceNameResolver; + this.name = name; + this.service = gXService; + } + + public string GetEncryptedPropertyValue(string propertyName) + { + String value = GetEncryptedPropertyValue(propertyName, null); + if (value == null) + { + String errorMessage = String.Format($"Service configuration error - Property name {ResolvePropertyName(propertyName)} must be defined"); + logger.Fatal(errorMessage); + throw new Exception(errorMessage); + } + return value; + } + public string GetEncryptedPropertyValue(string propertyName, string defaultValue) + { + String value = GetPropertyValue(propertyName, defaultValue); + if (!String.IsNullOrEmpty(value)) + { + try + { + string ret = String.Empty; + if (CryptoImpl.Decrypt(ref ret, value)) + { + value = ret; + } + } + catch (Exception) + { + logger.Warn($"Could not decrypt property name: {ResolvePropertyName(propertyName)}"); + } + } + return value; + } + + public string GetPropertyValue(string propertyName) + { + String value = GetPropertyValue(propertyName, null); + if (value == null) + { + String errorMessage = String.Format($"Service configuration error - Property name {ResolvePropertyName(propertyName)} must be defined"); + logger.Fatal(errorMessage); + throw new Exception(errorMessage); + } + return value; + } + + public string GetPropertyValue(string propertyName, string defaultValue) + { + String value = null; + value = string.IsNullOrEmpty(value) ? GetPropertyValueImpl(ResolvePropertyName(propertyName)) : value; + value = string.IsNullOrEmpty(value) ? GetPropertyValueImpl(propertyName) : value; + value = string.IsNullOrEmpty(value) ? defaultValue : value; + return value; + } + + internal string GetPropertyValueImpl(string propertyName) + { + String value = null; + if (!string.IsNullOrEmpty(propertyName)) + { + value = Environment.GetEnvironmentVariable(propertyName); + if (service != null && value == null) + { + value = service.Properties.Get(propertyName); + } + } + return value; + } + + internal string ResolvePropertyName(string propertyName) + { + return $"${serviceNameResolver}_{name}_{propertyName}"; + } + } +} diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs similarity index 56% rename from dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs rename to dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index 0cd0b121f..fd1fd5c49 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelAspNetProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -4,21 +4,38 @@ using OpenTelemetry; using OpenTelemetry.Trace; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using GeneXus.Services; +using GeneXus.Services.Common; namespace GeneXus.Otel.AWS { - public class AWSOtelAspNetProvider : IOpenTelemetryProvider - { + public class AWSOtelProvider : IOpenTelemetryProvider + { + //private ServiceSettingsReader settingsReader; + + public AWSOtelProvider(GXService s) + { + + + } + + public bool InstrumentAspNetCoreApplication(IServiceCollection _) { + string oltpEndpoint = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT"); + Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() // for generating AWS X-Ray compliant trace IDs .AddOtlpExporter(options => { - options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + if (!string.IsNullOrEmpty(oltpEndpoint)) + { + options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + } }) - .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation() + .AddSqlClientInstrumentation() .AddAWSInstrumentation() .Build(); diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index ca25b9ae6..82798a788 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -13,9 +13,15 @@ - - - + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj index 63f6bc8e1..5eb01243c 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -8,15 +8,19 @@ GeneXus.OpenTelemetry.Lightstep.AspNet Lightstep OpenTelemetry for .NET GeneXus.OpenTelemetry.Lightstep.AspNet + true - - - - - - - + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs index d761ce250..34148b418 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -6,29 +6,60 @@ using OpenTelemetry.Trace; using OpenTelemetry.Resources; using log4net; +using GeneXus.Services; +using GeneXus.Services.Common; +using System.Net.Http; -namespace GeneXus.OpenTelemetry.Lightstep +namespace GeneXus.OpenTelemetry.Lightstep.AspNet { - public class LightStepOpenTelemetry : IOpenTelemetryProvider { private static readonly ILog log = LogManager.GetLogger(typeof(LightStepOpenTelemetry)); - private const string LIGHTSTEP_INGREST_URL = "https://ingest.lightstep.com:443"; + private const string LIGHTSTEP_INGREST_URL = "ingest.lightstep.com:443"; private const string LIGHTSTEP_ACCESS_TOKEN = "LS_ACCESS_TOKEN"; - public bool InstrumentAspNetCoreApplication(IServiceCollection services) - { - //OTEL_SERVICE_NAME - string serviceName = "GXServiceName"; - string serviceVersion = "1.0.0"; - //TODO: Read dinamically. + private string AccessToken; + private string ServiceName; + private ServiceSettingsReader settingsReader; + + public LightStepOpenTelemetry(GXService s) + { + settingsReader = new ServiceSettingsReader(String.Empty, s.Name, s); - string lightstepToken = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); + AccessToken = settingsReader.GetPropertyValue("LIGHTSTEP_ACCESS_TOKEN", String.Empty); + ServiceName = settingsReader.GetPropertyValue("OPENTELEMETRY_SERVICE_NAME", String.Empty); + + string envVarValue = Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME"); + if (!String.IsNullOrEmpty(envVarValue)) + { + ServiceName = envVarValue; + } + + envVarValue = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); + if (!String.IsNullOrEmpty(envVarValue)) + { + AccessToken = envVarValue; + } - if (string.IsNullOrEmpty(lightstepToken)) + if (string.IsNullOrEmpty(ServiceName)) + { + log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'OTEL_SERVICE_NAME' Environment Variable"); + } + + if (string.IsNullOrEmpty(AccessToken)) { log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'LS_ACCESS_TOKEN' Environment Variable"); + } + } + + public bool InstrumentAspNetCoreApplication(IServiceCollection services) + { + if (String.IsNullOrEmpty(AccessToken) || String.IsNullOrEmpty(ServiceName)) + { + log.Warn("OpenTelemetry Lightstep was not initialized due to missing configuration"); return false; } + string serviceVersion = "1.0.0"; + //TODO: Read dinamically. services.AddOpenTelemetryTracing(tracerProviderBuilder => { @@ -36,14 +67,15 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) .AddOtlpExporter(opt => { opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); - opt.Headers = $"lightstep-access-token=${lightstepToken}"; + opt.Headers = $"lightstep-access-token=${AccessToken}"; }) - .AddSource(serviceName) + .AddSource(ServiceName) .SetResourceBuilder( ResourceBuilder.CreateDefault() - .AddService(serviceName: serviceName, serviceVersion: serviceVersion)) + .AddService(serviceName: ServiceName, serviceVersion: serviceVersion)) .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation(); + .AddAspNetCoreInstrumentation() + .AddSqlClientInstrumentation(); }); return true; diff --git a/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs index 1d458cc3d..929176203 100644 --- a/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs +++ b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs @@ -18,8 +18,7 @@ public static void SetupLog4Net() } private static void SetupLog4NetFromEnvironmentVariables() - { - System.Diagnostics.Debugger.Launch(); + { string logLevel = Environment.GetEnvironmentVariable(LOGLEVEL_ENVVAR); if (!string.IsNullOrEmpty(logLevel)) diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs index 8b116938b..c452e5091 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs @@ -973,7 +973,7 @@ private bool CheckFileExists(string fileName) { string path = Path.Combine(this.GetPhysicalPath(), fileName); fileExists = File.Exists(path); - GXLogging.Info(log, $"Searching if file exists ({fileName}). Found: {fileExists}"); + GXLogging.Debug(log, $"Searching if file exists ({fileName}). Found: {fileExists}"); } catch (Exception e) { From 1a7af3cb055cd11a40970083f69daa1dd04b64c0 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 16:18:31 -0300 Subject: [PATCH 05/18] Ignore PreRelease build warning --- .../GeneXus.OpenTelemetry.AWS.AspNet.csproj | 17 +++++++++-------- ...eneXus.OpenTelemetry.Lightstep.AspNet.csproj | 16 ++++++++-------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index 82798a788..d4eb2d71e 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -8,19 +8,20 @@ GeneXus.OpenTelemetry.AWS.AspNet AWS Distro for OpenTelemetry for .NET GeneXus.OpenTelemetry.AWS.AspNet + true - - - - - - - - + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj index 5eb01243c..bceca63bc 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -12,14 +12,14 @@ - - - - - - - - + + + + + + + + From 78939fc4f1495ac1d07e7359bfa045fc4181b525 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 16:24:34 -0300 Subject: [PATCH 06/18] Formatting ISsues --- dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs | 12 ++++++------ .../OpenTelemetryAWSOtel/AWSOtelProvider.cs | 5 ----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs index ca0494356..7b6531cb9 100644 --- a/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs +++ b/dotnet/src/dotnetcore/GxNetCoreStartup/Startup.cs @@ -79,7 +79,7 @@ public static IWebHost BuildWebHostPort(string[] args, string port) static IWebHost BuildWebHostPort(string[] args, string port, string schema) { return WebHost.CreateDefaultBuilder(args) - .ConfigureLogging(logging => logging.AddConsole()) + .ConfigureLogging(logging => logging.AddConsole()) .UseUrls($"{schema}://*:{port}") .UseStartup() .Build(); @@ -89,7 +89,7 @@ static IWebHost BuildWebHostPort(string[] args, string port, string schema) public static class GXHandlerExtensions { public static IApplicationBuilder UseGXHandlerFactory(this IApplicationBuilder builder, string basePath) - { + { return builder.UseMiddleware(basePath); } public static IApplicationBuilder MapWebSocketManager(this IApplicationBuilder app, string basePath) @@ -150,7 +150,7 @@ public void ConfigureServices(IServiceCollection services) options.AllowSynchronousIO = true; }); services.AddDistributedMemoryCache(); - + services.Configure(options => { if (Config.GetValueOf("MaxFileUploadSize", out string MaxFileUploadSizeStr) && long.TryParse(MaxFileUploadSizeStr, out long MaxFileUploadSize)) @@ -267,7 +267,7 @@ private void ConfigureSessionService(IServiceCollection services, ISessionServic } } public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory) - { + { string baseVirtualPath = string.IsNullOrEmpty(VirtualPath) ? VirtualPath : $"/{VirtualPath}"; LogConfiguration.SetupLog4Net(); var provider = new FileExtensionContentTypeProvider(); @@ -437,8 +437,8 @@ private void ConfigureSwaggerUI(IApplicationBuilder app, string baseVirtualPath) { Console.Error.WriteLine("Errpr loading SwaggerUI " + ex.Message); } - } - + } + private void AddRewrite(IApplicationBuilder app, string rewriteFile, string baseURL) { string rules = File.ReadAllText(rewriteFile); diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index fd1fd5c49..611c4e4ef 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -11,15 +11,10 @@ namespace GeneXus.Otel.AWS { public class AWSOtelProvider : IOpenTelemetryProvider { - //private ServiceSettingsReader settingsReader; - public AWSOtelProvider(GXService s) { - - } - public bool InstrumentAspNetCoreApplication(IServiceCollection _) { string oltpEndpoint = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT"); From 4c113e66217539f64cc6ccfcde3c5096745b73d7 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 16:25:40 -0300 Subject: [PATCH 07/18] Fix conventions --- .../LightstepProvider.cs | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs index 34148b418..202178872 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -1,14 +1,12 @@ using System; +using GeneXus.Services; +using GeneXus.Services.Common; using GeneXus.Services.OpenTelemetry; +using log4net; using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry; -using OpenTelemetry.Trace; using OpenTelemetry.Resources; -using log4net; -using GeneXus.Services; -using GeneXus.Services.Common; -using System.Net.Http; +using OpenTelemetry.Trace; namespace GeneXus.OpenTelemetry.Lightstep.AspNet { @@ -17,35 +15,35 @@ public class LightStepOpenTelemetry : IOpenTelemetryProvider private static readonly ILog log = LogManager.GetLogger(typeof(LightStepOpenTelemetry)); private const string LIGHTSTEP_INGREST_URL = "ingest.lightstep.com:443"; private const string LIGHTSTEP_ACCESS_TOKEN = "LS_ACCESS_TOKEN"; - private string AccessToken; - private string ServiceName; + private string accessToken; + private string serviceName; private ServiceSettingsReader settingsReader; public LightStepOpenTelemetry(GXService s) { settingsReader = new ServiceSettingsReader(String.Empty, s.Name, s); - AccessToken = settingsReader.GetPropertyValue("LIGHTSTEP_ACCESS_TOKEN", String.Empty); - ServiceName = settingsReader.GetPropertyValue("OPENTELEMETRY_SERVICE_NAME", String.Empty); + accessToken = settingsReader.GetPropertyValue("LIGHTSTEP_ACCESS_TOKEN", String.Empty); + serviceName = settingsReader.GetPropertyValue("OPENTELEMETRY_SERVICE_NAME", String.Empty); string envVarValue = Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME"); if (!String.IsNullOrEmpty(envVarValue)) { - ServiceName = envVarValue; + serviceName = envVarValue; } envVarValue = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); if (!String.IsNullOrEmpty(envVarValue)) { - AccessToken = envVarValue; + accessToken = envVarValue; } - if (string.IsNullOrEmpty(ServiceName)) + if (string.IsNullOrEmpty(serviceName)) { log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'OTEL_SERVICE_NAME' Environment Variable"); } - if (string.IsNullOrEmpty(AccessToken)) + if (string.IsNullOrEmpty(accessToken)) { log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'LS_ACCESS_TOKEN' Environment Variable"); } @@ -53,7 +51,7 @@ public LightStepOpenTelemetry(GXService s) public bool InstrumentAspNetCoreApplication(IServiceCollection services) { - if (String.IsNullOrEmpty(AccessToken) || String.IsNullOrEmpty(ServiceName)) + if (String.IsNullOrEmpty(accessToken) || String.IsNullOrEmpty(serviceName)) { log.Warn("OpenTelemetry Lightstep was not initialized due to missing configuration"); return false; @@ -67,12 +65,12 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) .AddOtlpExporter(opt => { opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); - opt.Headers = $"lightstep-access-token=${AccessToken}"; + opt.Headers = $"lightstep-access-token=${accessToken}"; }) - .AddSource(ServiceName) + .AddSource(serviceName) .SetResourceBuilder( ResourceBuilder.CreateDefault() - .AddService(serviceName: ServiceName, serviceVersion: serviceVersion)) + .AddService(serviceName: serviceName, serviceVersion: serviceVersion)) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation() .AddSqlClientInstrumentation(); From 243aea52edcebadd4f7565a06c994971fbf07157 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 16:27:03 -0300 Subject: [PATCH 08/18] Ignore NU5104 --- .../GeneXus.OpenTelemetry.AWS.AspNet.csproj | 18 +++++++++--------- ...neXus.OpenTelemetry.Lightstep.AspNet.csproj | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index d4eb2d71e..b74d6ddf0 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -14,14 +14,14 @@ - - - - - - - - + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj index bceca63bc..37d59247a 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -12,14 +12,14 @@ - - - - - - - - + + + + + + + + From c9e0ed94122422552c613fc834e5a1d01e284c29 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 17:19:33 -0300 Subject: [PATCH 09/18] Fix Namespace --- .../OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index 611c4e4ef..346f49259 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -7,7 +7,7 @@ using GeneXus.Services; using GeneXus.Services.Common; -namespace GeneXus.Otel.AWS +namespace GeneXus.OpenTelemetry.AWS { public class AWSOtelProvider : IOpenTelemetryProvider { From 73beecb0e6be53bf34a1afda067a148616acd1ef Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 21 Dec 2022 17:31:03 -0300 Subject: [PATCH 10/18] Remove unused code & project --- .../OpenTelemetryAWSOtel/AWSOtelProvider.cs | 2 +- .../GXOpenTelemetry/GXOpenTelemetry.csproj | 9 --- .../GXOpenTelemetry/OpenTelemetryService.cs | 62 ------------------- 3 files changed, 1 insertion(+), 72 deletions(-) delete mode 100644 dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj delete mode 100644 dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index 346f49259..c863a0b6c 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -25,7 +25,7 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection _) { if (!string.IsNullOrEmpty(oltpEndpoint)) { - options.Endpoint = new Uri(Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")); + options.Endpoint = new Uri(oltpEndpoint); } }) .AddHttpClientInstrumentation() diff --git a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj deleted file mode 100644 index 132c02c59..000000000 --- a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/GXOpenTelemetry.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net6.0 - enable - enable - - - diff --git a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs deleted file mode 100644 index 5f77a0ccb..000000000 --- a/dotnet/src/dotnetcore/Services/GXOpenTelemetry/OpenTelemetryService.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace GXOpenTelemetry -{ - public class OpenTelemetryService - { - - public static Instance - { - get - { - if (instance == null) - { - lock (syncRoot) - { - if (instance == null) - { - - GXServices services = GXServices.Instance; - if (services != null) - { - GXService providerService = services.Get(GXServices.CACHE_SERVICE); - if (providerService != null) - { - GXLogging.Debug(log, "Loading CACHE_PROVIDER: ", providerService.ClassName); - try - { -#if NETCORE - Type type = AssemblyLoader.GetType(providerService.ClassName); -#else - Type type = Type.GetType(providerService.ClassName, true, true); -#endif - instance = (ICacheService)Activator.CreateInstance(type); - if (providerService.Properties.ContainsKey(FORCE_HIGHEST_TIME_TO_LIVE)) - { - int ttl; - if (Int32.TryParse(providerService.Properties.Get(FORCE_HIGHEST_TIME_TO_LIVE), out ttl) && ttl == 1) - { - forceHighestTimetoLive = true; - } - } - } - catch (Exception e) - { - GXLogging.Error(log, "Couldn't create CACHE_PROVIDER as ICacheService: ", providerService.ClassName, e); - throw e; - } - } - } - if (instance == null) - { - GXLogging.Debug(log, "Loading Default CACHE_PROVIDER InMemoryCache"); - instance = new InProcessCache(); - } - } - } - } - - return instance; - } - } - - } -} \ No newline at end of file From 9d3ca40ea6d87baa1623107415ace747a0adc4ac Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 22 Dec 2022 09:59:00 -0300 Subject: [PATCH 11/18] Configure OTEL --- .../OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index c863a0b6c..d4c714cd8 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -28,8 +28,12 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection _) options.Endpoint = new Uri(oltpEndpoint); } }) + .SetErrorStatusOnException(true) .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation() + .AddAspNetCoreInstrumentation(opt => + { + opt.RecordException = true; + }) .AddSqlClientInstrumentation() .AddAWSInstrumentation() .Build(); From 8fd97fb1eeedbda14beaa483ce29cc92e404d571 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 22 Dec 2022 11:50:57 -0300 Subject: [PATCH 12/18] Improve project metadata --- .../GeneXus.OpenTelemetry.AWS.AspNet.csproj | 7 +++---- .../GeneXus.OpenTelemetry.Lightstep.AspNet.csproj | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index b74d6ddf0..6aa0e70ad 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -2,13 +2,12 @@ net6.0 - TRACE;DEBUG;NETCORE + NETCORE; Properties false GeneXus.OpenTelemetry.AWS.AspNet - AWS Distro for OpenTelemetry for .NET - GeneXus.OpenTelemetry.AWS.AspNet - true + AWSOtel OpenDistro OpenTelemetry GeneXus + GeneXus.OpenTelemetry.AWS.AspNet diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj index 37d59247a..007814068 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -2,13 +2,12 @@ net6.0 - TRACE;DEBUG;NETCORE + NETCORE; Properties false GeneXus.OpenTelemetry.Lightstep.AspNet - Lightstep OpenTelemetry for .NET - GeneXus.OpenTelemetry.Lightstep.AspNet - true + Lightstep OpenTelemetry GeneXus DotNet + GeneXus.OpenTelemetry.Lightstep.AspNet From 6e66363e26720c183412c0580ff7c4de25627671 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 22 Dec 2022 15:52:13 -0300 Subject: [PATCH 13/18] Add MYSQL Instrumentation --- .../OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index d4c714cd8..33b21ca4f 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -29,6 +29,7 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection _) } }) .SetErrorStatusOnException(true) + .AddSource("MySqlConnector") .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation(opt => { From 067f6a799e0f5b4d4b45ddad4dfb192358775066 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 27 Dec 2022 10:27:03 -0300 Subject: [PATCH 14/18] Add OpenTelemetry Provider --- dotnet/DotNetStandardClasses.sln | 9 ++- .../GeneXus.OpenTelemetry.csproj | 28 ++++++++ .../OpenTelemetry/OpenTelemetryProvider.cs | 33 +++++++++ .../LightstepProvider.cs | 71 ++++++------------- 4 files changed, 91 insertions(+), 50 deletions(-) create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs diff --git a/dotnet/DotNetStandardClasses.sln b/dotnet/DotNetStandardClasses.sln index 3cddcb3ad..2df891d39 100644 --- a/dotnet/DotNetStandardClasses.sln +++ b/dotnet/DotNetStandardClasses.sln @@ -224,10 +224,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCoreWebUnitTest", "te EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opentelemetry", "opentelemetry", "{BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneXus.OpenTelemetry.Lightstep.AspNet", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetryLightStep\GeneXus.OpenTelemetry.Lightstep.AspNet.csproj", "{27D54041-BDD5-428E-8CA6-C96D519F5451}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneXus.OpenTelemetry.Lightstep.AspNet", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetryLightStep\GeneXus.OpenTelemetry.Lightstep.AspNet.csproj", "{27D54041-BDD5-428E-8CA6-C96D519F5451}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeneXus.OpenTelemetry.AWS.AspNet", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetryAWSOtel\GeneXus.OpenTelemetry.AWS.AspNet.csproj", "{B5A9DEA7-67EC-49E4-924E-4729C34286EC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeneXus.OpenTelemetry", "src\dotnetcore\Providers\OpenTelemetry\OpenTelemetry\GeneXus.OpenTelemetry.csproj", "{00B1FA38-7D0B-47E4-860C-23490249A4D6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -554,6 +556,10 @@ Global {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Debug|Any CPU.Build.0 = Debug|Any CPU {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {B5A9DEA7-67EC-49E4-924E-4729C34286EC}.Release|Any CPU.Build.0 = Release|Any CPU + {00B1FA38-7D0B-47E4-860C-23490249A4D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00B1FA38-7D0B-47E4-860C-23490249A4D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00B1FA38-7D0B-47E4-860C-23490249A4D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00B1FA38-7D0B-47E4-860C-23490249A4D6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -664,6 +670,7 @@ Global {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} = {2261B65E-3757-4E5B-9DCD-EAE8D1E236A3} {27D54041-BDD5-428E-8CA6-C96D519F5451} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} {B5A9DEA7-67EC-49E4-924E-4729C34286EC} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} + {00B1FA38-7D0B-47E4-860C-23490249A4D6} = {BBE020D4-C0FF-41A9-9EB1-D1EE12CC4BB8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E18684C9-7D76-45CD-BF24-E3944B7F174C} diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj new file mode 100644 index 000000000..fba026b94 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GeneXus.OpenTelemetry.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + enable + enable + GeneXus.OpenTelemetry + OpenTelemetry GeneXus DotNet + GeneXus.OpenTelemetry.OpenTelemetry + + + + + + + + + + + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs new file mode 100644 index 000000000..67e2f6c25 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs @@ -0,0 +1,33 @@ +using GeneXus.Services; +using GeneXus.Services.OpenTelemetry; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Trace; + +namespace GeneXus.OpenTelemetry.OpenTelemetry +{ + public class OpenTelemetryProvider : IOpenTelemetryProvider + { + public OpenTelemetryProvider(GXService s) + { + } + + public bool InstrumentAspNetCoreApplication(IServiceCollection services) + { + services.AddOpenTelemetryTracing(tracerProviderBuilder => + { + tracerProviderBuilder + .AddOtlpExporter() + .SetErrorStatusOnException(true) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation(opt => + { + opt.RecordException = true; + }) + .AddSqlClientInstrumentation() + .Build(); + }); + + return true; + } + } +} \ No newline at end of file diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs index 202178872..b10ca1780 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -1,63 +1,35 @@ using System; -using GeneXus.Services; -using GeneXus.Services.Common; using GeneXus.Services.OpenTelemetry; -using log4net; using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Resources; +using OpenTelemetry; using OpenTelemetry.Trace; +using OpenTelemetry.Resources; +using log4net; +using GeneXus.Services; -namespace GeneXus.OpenTelemetry.Lightstep.AspNet +namespace GeneXus.OpenTelemetry.Lightstep { + public class LightStepOpenTelemetry : IOpenTelemetryProvider { private static readonly ILog log = LogManager.GetLogger(typeof(LightStepOpenTelemetry)); - private const string LIGHTSTEP_INGREST_URL = "ingest.lightstep.com:443"; + private const string LIGHTSTEP_INGREST_URL = "https://ingest.lightstep.com:443"; private const string LIGHTSTEP_ACCESS_TOKEN = "LS_ACCESS_TOKEN"; - private string accessToken; - private string serviceName; - private ServiceSettingsReader settingsReader; public LightStepOpenTelemetry(GXService s) - { - settingsReader = new ServiceSettingsReader(String.Empty, s.Name, s); - - accessToken = settingsReader.GetPropertyValue("LIGHTSTEP_ACCESS_TOKEN", String.Empty); - serviceName = settingsReader.GetPropertyValue("OPENTELEMETRY_SERVICE_NAME", String.Empty); - - string envVarValue = Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME"); - if (!String.IsNullOrEmpty(envVarValue)) - { - serviceName = envVarValue; - } - - envVarValue = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); - if (!String.IsNullOrEmpty(envVarValue)) - { - accessToken = envVarValue; - } - - if (string.IsNullOrEmpty(serviceName)) - { - log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'OTEL_SERVICE_NAME' Environment Variable"); - } - - if (string.IsNullOrEmpty(accessToken)) - { - log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'LS_ACCESS_TOKEN' Environment Variable"); - } + { } public bool InstrumentAspNetCoreApplication(IServiceCollection services) { - if (String.IsNullOrEmpty(accessToken) || String.IsNullOrEmpty(serviceName)) + string lightstepToken = Environment.GetEnvironmentVariable(LIGHTSTEP_ACCESS_TOKEN); + + if (string.IsNullOrEmpty(lightstepToken)) { - log.Warn("OpenTelemetry Lightstep was not initialized due to missing configuration"); + log.Warn("OpenTelemetry Lightstep was not initialized due to missing 'LS_ACCESS_TOKEN' Environment Variable"); return false; } - string serviceVersion = "1.0.0"; - //TODO: Read dinamically. services.AddOpenTelemetryTracing(tracerProviderBuilder => { @@ -65,15 +37,16 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) .AddOtlpExporter(opt => { opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); - opt.Headers = $"lightstep-access-token=${accessToken}"; - }) - .AddSource(serviceName) - .SetResourceBuilder( - ResourceBuilder.CreateDefault() - .AddService(serviceName: serviceName, serviceVersion: serviceVersion)) - .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation() - .AddSqlClientInstrumentation(); + opt.Headers = $"lightstep-access-token=${lightstepToken}"; + }) + .SetErrorStatusOnException(true) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation(opt => + { + opt.RecordException = true; + }) + .AddSqlClientInstrumentation() + .Build(); }); return true; From 6a10a67a8ba585e82c79b11fc54e184e8eecd4e5 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 27 Dec 2022 14:05:23 -0300 Subject: [PATCH 15/18] Log Configuration via EnvVars --- .../Configuration/LogConfiguration.cs | 46 +++++++++++++++---- .../GxClasses/Core/gxconfig.cs | 1 + 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs index 929176203..43495ecf7 100644 --- a/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs +++ b/dotnet/src/dotnetframework/GxClasses/Configuration/LogConfiguration.cs @@ -1,16 +1,22 @@ using System; using log4net; +using log4net.Appender; using log4net.Core; using log4net.Repository; using log4net.Repository.Hierarchy; +using System.Linq; +using log4net.Layout; namespace GeneXus.Configuration { - internal static class LogConfiguration + internal class LogConfiguration { - public const string USER_LOG_TOPIC = "GeneXusUserLog"; - private const string LOGLEVEL_ENVVAR = "GX_LOG_LEVEL"; - private const string USERLOGLEVEL_ENVVAR = "GX_LOG_LEVEL_USER"; + private static readonly ILog logger = log4net.LogManager.GetLogger(typeof(LogConfiguration)); + + public const string USER_LOG_TOPIC = "GeneXusUserLog"; + private const string LOG_LEVEL_ENVVAR = "GX_LOG_LEVEL"; + private const string LOG_LEVEL_USER_ENVVAR = "GX_LOG_LEVEL_USER"; + private const string LOG_OUTPUT_ENVVAR = "GX_LOG_OUTPUT"; public static void SetupLog4Net() { @@ -18,8 +24,8 @@ public static void SetupLog4Net() } private static void SetupLog4NetFromEnvironmentVariables() - { - string logLevel = Environment.GetEnvironmentVariable(LOGLEVEL_ENVVAR); + { + string logLevel = Environment.GetEnvironmentVariable(LOG_LEVEL_ENVVAR); if (!string.IsNullOrEmpty(logLevel)) { @@ -27,7 +33,7 @@ private static void SetupLog4NetFromEnvironmentVariables() h.Root.Level = h.LevelMap[logLevel.ToUpper()]; } - string userLogLevel = Environment.GetEnvironmentVariable(USERLOGLEVEL_ENVVAR); + string userLogLevel = Environment.GetEnvironmentVariable(LOG_LEVEL_USER_ENVVAR); if (!string.IsNullOrEmpty(userLogLevel)) { @@ -36,9 +42,33 @@ private static void SetupLog4NetFromEnvironmentVariables() { Hierarchy hier = (Hierarchy)repository; ILogger logger = hier.GetLogger(USER_LOG_TOPIC); - ((Logger)logger).Level = hier.LevelMap[userLogLevel]; + if (logger != null) + { + ((Logger)logger).Level = hier.LevelMap[userLogLevel]; + } + } + } + + string appenderName = Environment.GetEnvironmentVariable(LOG_OUTPUT_ENVVAR); + if (!String.IsNullOrEmpty(appenderName)) + { + Hierarchy h = (Hierarchy) LogManager.GetRepository(); + IAppender appenderToAdd = h.GetAppenders().First(a => a.Name == appenderName); + if (appenderToAdd == null) + { + LogConfiguration.logger.Error($"Appender '{appenderName}' was not found on Log4Net Config file"); + return; } + + h.Root.AddAppender(appenderToAdd); + ILogger logger = h.GetLogger(USER_LOG_TOPIC); + if (logger != null) + { + ((Logger)logger).AddAppender(appenderToAdd); + } + } } + } } diff --git a/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs b/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs index 7443d0f67..f59aff718 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/gxconfig.cs @@ -80,6 +80,7 @@ public static void ParseArgs(ref string[] args) } } + LogConfiguration.SetupLog4Net(); } private static void RemoveArg(ref string[] args, ref int i) From 6bdf9979612517b5a4fa1d775fa1714393595896 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Tue, 27 Dec 2022 15:11:31 -0300 Subject: [PATCH 16/18] Do not copy Test Dependencies on msbuild deploy --- .../test/GeneXus.Programs.Common/GeneXus.Programs.Common.csproj | 1 + .../extensions/Azure/test/apiattractions/apiattractions.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/dotnet/src/extensions/Azure/test/GeneXus.Programs.Common/GeneXus.Programs.Common.csproj b/dotnet/src/extensions/Azure/test/GeneXus.Programs.Common/GeneXus.Programs.Common.csproj index 85b46302a..c445f203f 100644 --- a/dotnet/src/extensions/Azure/test/GeneXus.Programs.Common/GeneXus.Programs.Common.csproj +++ b/dotnet/src/extensions/Azure/test/GeneXus.Programs.Common/GeneXus.Programs.Common.csproj @@ -2,6 +2,7 @@ net6.0 + false diff --git a/dotnet/src/extensions/Azure/test/apiattractions/apiattractions.csproj b/dotnet/src/extensions/Azure/test/apiattractions/apiattractions.csproj index 12c8a31ed..bb8cc1893 100644 --- a/dotnet/src/extensions/Azure/test/apiattractions/apiattractions.csproj +++ b/dotnet/src/extensions/Azure/test/apiattractions/apiattractions.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + false From 1a9d141147154903dc92a07a1981fdb9fe3f6019 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Wed, 28 Dec 2022 14:05:10 -0300 Subject: [PATCH 17/18] Fix minor Issues OTEL --- .../OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs | 3 +-- .../OpenTelemetryLightStep/LightstepProvider.cs | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs index 67e2f6c25..a4a357b3c 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs @@ -23,8 +23,7 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) { opt.RecordException = true; }) - .AddSqlClientInstrumentation() - .Build(); + .AddSqlClientInstrumentation(); }); return true; diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs index b10ca1780..e989090b0 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -14,7 +14,7 @@ namespace GeneXus.OpenTelemetry.Lightstep public class LightStepOpenTelemetry : IOpenTelemetryProvider { private static readonly ILog log = LogManager.GetLogger(typeof(LightStepOpenTelemetry)); - private const string LIGHTSTEP_INGREST_URL = "https://ingest.lightstep.com:443"; + private const string LIGHTSTEP_INGREST_URL = "ingest.lightstep.com:443"; private const string LIGHTSTEP_ACCESS_TOKEN = "LS_ACCESS_TOKEN"; public LightStepOpenTelemetry(GXService s) @@ -37,16 +37,15 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) .AddOtlpExporter(opt => { opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); - opt.Headers = $"lightstep-access-token=${lightstepToken}"; - }) + opt.Headers = $"lightstep-access-token=${lightstepToken}"; + }) .SetErrorStatusOnException(true) .AddHttpClientInstrumentation() .AddAspNetCoreInstrumentation(opt => { opt.RecordException = true; }) - .AddSqlClientInstrumentation() - .Build(); + .AddSqlClientInstrumentation(); }); return true; From 985c4500fffb19126906e8247adf7ac369696193 Mon Sep 17 00:00:00 2001 From: Gonzalo Gallotti Date: Thu, 29 Dec 2022 18:10:14 -0300 Subject: [PATCH 18/18] OTEL Improvements --- .../Diagnostics/GxHttpActivitySourceHelper.cs | 38 +++++++++++++++++++ .../OpenTelemetry/OpenTelemetryService.cs | 3 +- .../OpenTelemetry/GxTraceProviderBuilder.cs | 36 ++++++++++++++++++ .../OpenTelemetry/OpenTelemetryProvider.cs | 11 ++---- .../OpenTelemetryAWSOtel/AWSOtelProvider.cs | 11 +----- .../GeneXus.OpenTelemetry.AWS.AspNet.csproj | 17 +++++---- ...eXus.OpenTelemetry.Lightstep.AspNet.csproj | 13 ++++--- .../LightstepProvider.cs | 8 +--- .../GxClasses/Services/GxRestWrapper.cs | 5 +++ 9 files changed, 103 insertions(+), 39 deletions(-) create mode 100644 dotnet/src/dotnetcore/GxClasses/Diagnostics/GxHttpActivitySourceHelper.cs create mode 100644 dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs diff --git a/dotnet/src/dotnetcore/GxClasses/Diagnostics/GxHttpActivitySourceHelper.cs b/dotnet/src/dotnetcore/GxClasses/Diagnostics/GxHttpActivitySourceHelper.cs new file mode 100644 index 000000000..1d88564f2 --- /dev/null +++ b/dotnet/src/dotnetcore/GxClasses/Diagnostics/GxHttpActivitySourceHelper.cs @@ -0,0 +1,38 @@ +using System; +using System.Diagnostics; +using System.Reflection; + + +namespace GeneXus.Diagnostics +{ + public static class GxHttpActivitySourceHelper + { + public static string GX_HTTP_INSTRUMENTATION = "GeneXus.Instrumentation.Http"; + private static ActivitySource ActivitySource { get; } = CreateActivitySource(); + + public const string ThreadIdTagName = "thread.id"; + public const string StatusCodeTagName = "otel.status_code"; + + private static ActivitySource CreateActivitySource() + { + Assembly assembly = typeof(GxHttpActivitySourceHelper).Assembly; + string version = assembly.GetCustomAttribute()!.Version; + return new ActivitySource(GX_HTTP_INSTRUMENTATION, version); + } + + public static void SetException(Activity activity, Exception exception) + { + string description = exception.Message; + activity?.SetStatus(ActivityStatusCode.Error, description); + activity?.SetTag(StatusCodeTagName, "ERROR"); + activity?.SetTag("otel.status_description", description); + activity?.AddEvent(new ActivityEvent("exception", tags: new ActivityTagsCollection + { + { "exception.type", exception.GetType().FullName }, + { "exception.message", exception.Message }, + { "exception.source", exception.Source }, + { "exception.stacktrace", exception.ToString() }, + })); + } + } +} diff --git a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs index f8936d606..125f05ff5 100644 --- a/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs +++ b/dotnet/src/dotnetcore/GxClasses/Services/OpenTelemetry/OpenTelemetryService.cs @@ -9,10 +9,11 @@ public interface IOpenTelemetryProvider bool InstrumentAspNetCoreApplication(Microsoft.Extensions.DependencyInjection.IServiceCollection services); } - internal static class OpenTelemetryService + public static class OpenTelemetryService { private static readonly ILog log = log4net.LogManager.GetLogger(typeof(OpenTelemetryService)); private static string OPENTELEMETRY_SERVICE = "Observability"; + public static string GX_ACTIVITY_SOURCE_NAME = "GeneXus.Tracing"; private static IOpenTelemetryProvider GetOpenTelemetryProvider() { diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs new file mode 100644 index 000000000..58da3b8d2 --- /dev/null +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/GxTraceProviderBuilder.cs @@ -0,0 +1,36 @@ +using GeneXus.Services.OpenTelemetry; +using OpenTelemetry.Trace; + +namespace GeneXus.OpenTelemetry +{ + public static class GxTraceProviderBuilder + { + public static TracerProviderBuilder AddGxAspNetInstrumentation(this TracerProviderBuilder tracer) + { + tracer + .AddAspNetCoreInstrumentation(opt => + { + opt.RecordException = true; + }) + .SetErrorStatusOnException(true) + .AddSource("MySqlConnector") + .AddSource(OpenTelemetryService.GX_ACTIVITY_SOURCE_NAME) + .AddHttpClientInstrumentation(opt => + { + opt.RecordException = true; + }) + .AddAspNetCoreInstrumentation(opt => + { + opt.RecordException = true; + }) + .AddSqlClientInstrumentation(opt => + { + opt.RecordException = true; + opt.EnableConnectionLevelAttributes = true; + opt.SetDbStatementForText = true; + }) + .AddConsoleExporter(); + return tracer; + } + } +} diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs index a4a357b3c..7b66e07b6 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetry/OpenTelemetryProvider.cs @@ -13,17 +13,12 @@ public OpenTelemetryProvider(GXService s) public bool InstrumentAspNetCoreApplication(IServiceCollection services) { + services.AddOpenTelemetryTracing(tracerProviderBuilder => { tracerProviderBuilder - .AddOtlpExporter() - .SetErrorStatusOnException(true) - .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation(opt => - { - opt.RecordException = true; - }) - .AddSqlClientInstrumentation(); + .AddOtlpExporter() + .AddGxAspNetInstrumentation(); }); return true; diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs index 33b21ca4f..2d9d10a04 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/AWSOtelProvider.cs @@ -6,6 +6,7 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; using GeneXus.Services; using GeneXus.Services.Common; +using GeneXus.Diagnostics; namespace GeneXus.OpenTelemetry.AWS { @@ -28,15 +29,7 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection _) options.Endpoint = new Uri(oltpEndpoint); } }) - .SetErrorStatusOnException(true) - .AddSource("MySqlConnector") - .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation(opt => - { - opt.RecordException = true; - }) - .AddSqlClientInstrumentation() - .AddAWSInstrumentation() + .AddGxAspNetInstrumentation() .Build(); Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj index 6aa0e70ad..094dfbd46 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryAWSOtel/GeneXus.OpenTelemetry.AWS.AspNet.csproj @@ -13,19 +13,20 @@ - - - - - - - - + + + + + + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj index 007814068..7d62fab6e 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/GeneXus.OpenTelemetry.Lightstep.AspNet.csproj @@ -11,18 +11,19 @@ - - - + + + - - - + + + + diff --git a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs index e989090b0..67fa41aa6 100644 --- a/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs +++ b/dotnet/src/dotnetcore/Providers/OpenTelemetry/OpenTelemetryLightStep/LightstepProvider.cs @@ -39,13 +39,7 @@ public bool InstrumentAspNetCoreApplication(IServiceCollection services) opt.Endpoint = new Uri(LIGHTSTEP_INGREST_URL); opt.Headers = $"lightstep-access-token=${lightstepToken}"; }) - .SetErrorStatusOnException(true) - .AddHttpClientInstrumentation() - .AddAspNetCoreInstrumentation(opt => - { - opt.RecordException = true; - }) - .AddSqlClientInstrumentation(); + .AddGxAspNetInstrumentation(); }); return true; diff --git a/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs b/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs index 7067963fb..9a60d158b 100644 --- a/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs +++ b/dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs @@ -28,6 +28,8 @@ using Jayrock.Json; using Microsoft.Net.Http.Headers; using System.Net.Http; +using System.Diagnostics; +using GeneXus.Diagnostics; namespace GeneXus.Application @@ -698,6 +700,9 @@ string dateTimeToHTMLDate(DateTime dt) } public Task WebException(Exception ex) { +#if NETCORE + GxHttpActivitySourceHelper.SetException(Activity.Current, ex); +#endif GXLogging.Error(log, "WebException", ex); if (ex is FormatException) {