Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

README update: Add Oracle .NET OpenTelemetry provider #3192

Closed
alexkeh opened this issue Dec 15, 2023 · 23 comments · Fixed by #3336
Closed

README update: Add Oracle .NET OpenTelemetry provider #3192

alexkeh opened this issue Dec 15, 2023 · 23 comments · Fixed by #3336
Assignees
Milestone

Comments

@alexkeh
Copy link

alexkeh commented Dec 15, 2023

Oracle recently released its .NET OpenTelemetry provider that works with both Oracle.ManagedDataAccess.Core (ODP.NET Core) and Oracle.ManagedDataAccess (managed ODP.NET). Can you update the Instrumentation Libraries README Databases table with the following or something similar?

Library Tracing Support Metrics Support Databases Tested Notes
Oracle.ManagedDataAccess.Core Yes Oracle Database Requires Oracle.ManagedDataAccess.OpenTelemetry NuGet package
Oracle.ManagedDataAccess Yes Oracle Database Requires Oracle.ManagedDataAccess.OpenTelemetry NuGet package

I realize I could file a PR with the README change. However, going through the EasyCLA from a corporate standpoint is a big unknown in terms of time commitment and effort to complete when the change is straightforward and the update is from public info.

Thanks!

@Kielek
Copy link
Contributor

Kielek commented Dec 18, 2023

@alexkeh,
Great to see that Oracle driver starts shipping native support for OpenTelemetry for pre-GA releases.
I hope you have still some time to consider following feedback and improve experience.

The ultimate solution for introducing native OTel support for traces for library is to just call TracerProviderBuilder.AddSource("YouLibraryNameActivitySource") without need to depend on any other external libraries. As an example please check MassTransit package which converted library based version to direct support.

I have checked what is doing Oracle.ManagedDataAccess.OpenTelemetry and the new version of Oracle.ManagedDataAccess package and IMO you are pretty close to this solution

From Oracle.ManagedDataAccess

public sealed class OracleCommand : DbCommand, ICloneable, IReplayBase
  {
    internal static bool IsOpenTelemetryEnabled = false;
    internal static OracleActivitySource OracleActivitySource;

  (...)
  // All Calls to OracleActivitySourceName are serrounded by this condition:
      if (OracleCommand.IsOpenTelemetryEnabled)
        activity = OracleCommand.OracleActivitySource.SpanStart(callingMethodName, command);
  }

and

using Oracle.ManagedDataAccess.Client;
using OracleInternal.ConnectionPool;
using OracleInternal.ServiceObjects;
using System;
using System.Data;
using System.Diagnostics;

namespace Oracle.ManagedDataAccess.OpenTelemetry
{
  internal class OracleActivitySource
  {
    internal static readonly ActivitySource m_Source = new ActivitySource("ODPNET");

    internal bool SetDbStatementForStoredProcedure { get; set; }

    internal bool SetDbStatementForText { get; set; }

    internal bool EnableConnectionLevelAttributes { get; set; }

    internal bool InstrumentOracleDataReaderRead { get; set; }

    internal bool RecordException { get; set; }

    internal bool EnableDBRoundTripTracing { get; set; }

    internal EnableOpenCloseTracing EnableOpenCloseTracing { get; set; }

    internal bool RequireApplicationRootSpanCreation { get; set; }

    internal object SpanStart(
      string activityDisplayName,
      OracleConnectionImpl connImpl = null,
      string sqlStatement = null,
      string statementType = null,
      ConnectionString cs = null,
      object parentActivity = null)
    {
      try
      {
        if (this.RequireApplicationRootSpanCreation && Activity.Current == null)
          return (object) null;
        Activity activity = parentActivity == null || string.IsNullOrWhiteSpace((parentActivity as Activity).Id) ? OracleActivitySource.m_Source.StartActivity(activityDisplayName, ActivityKind.Client) : OracleActivitySource.m_Source.StartActivity(activityDisplayName, ActivityKind.Client, (parentActivity as Activity).Id);
        if (activity != null)
        {
          activity.IsAllDataRequested = true;
          activity.SetTag("db.system", (object) "oracle");
          if (connImpl != null && this.EnableConnectionLevelAttributes)
          {
            activity.SetTag("db.name", (object) connImpl.m_databaseName);
            if (connImpl.m_cs != null)
            {
              activity.SetTag("db.connection_string", (object) connImpl.m_cs.m_passwlessConString);
              activity.SetTag("db.user", (object) connImpl.m_cs.m_userId);
            }
            else if (cs != null)
            {
              activity.SetTag("db.connection_string", (object) cs.m_passwlessConString);
              activity.SetTag("db.user", (object) cs.m_userId);
            }
          }
          else if (cs != null && this.EnableConnectionLevelAttributes)
          {
            activity.SetTag("db.connection_string", (object) cs.m_passwlessConString);
            activity.SetTag("db.user", (object) cs.m_userId);
          }
          if (!string.IsNullOrWhiteSpace(sqlStatement))
          {
            if (statementType == CommandType.StoredProcedure.ToString() && this.SetDbStatementForStoredProcedure)
              activity.SetTag("db.statement", (object) sqlStatement);
            else if (statementType == CommandType.Text.ToString() && this.SetDbStatementForText)
              activity.SetTag("db.statement", (object) sqlStatement);
            else if (statementType == CommandType.TableDirect.ToString())
              activity.SetTag("db.statement", (object) sqlStatement);
          }
        }
        return (object) activity;
      }
      catch
      {
        return (object) null;
      }
    }

    internal object SpanStart(string activityDisplayName, OracleCommand command = null) => command != null ? this.SpanStart(activityDisplayName, command.Connection.m_oracleConnectionImpl, command.CommandText, command.CommandType.ToString()) : this.SpanStart(activityDisplayName, (OracleConnectionImpl) null, (string) null, (string) null, (ConnectionString) null, (object) null);

    internal object SpanStart(
      string activityDisplayName,
      OracleConnectionImpl connImpl = null,
      OracleCommandImpl command = null)
    {
      return command != null ? this.SpanStart(activityDisplayName, connImpl, command.m_commandText, command.m_commandType.ToString()) : this.SpanStart(activityDisplayName, connImpl, (string) null, (string) null, (ConnectionString) null, (object) null);
    }

    internal object SpanStart(
      string activityDisplayName,
      OracleConnectionImpl connImpl = null,
      OracleCommandImpl command = null,
      ConnectionString cs = null,
      object parentActivity = null)
    {
      return command != null ? this.SpanStart(activityDisplayName, connImpl, command.m_commandText, command.m_commandType.ToString(), cs, parentActivity) : this.SpanStart(activityDisplayName, connImpl, (string) null, (string) null, cs, parentActivity);
    }

    internal void SpanStop(object activity, string dbname = "")
    {
      try
      {
        if (activity == null)
          return;
        ((Activity) activity).SetTag("otel.status_code", (object) "OK");
        if (!string.IsNullOrEmpty(dbname))
          ((Activity) activity).SetTag("db.name", (object) dbname);
        ((Activity) activity).Dispose();
      }
      catch
      {
      }
    }

    internal void SetException(object activity, Exception ex)
    {
      try
      {
        if (activity == null || !this.RecordException)
          return;
        if (ex != null)
        {
          ActivityTagsCollection tags = new ActivityTagsCollection()
          {
            {
              "exception.type",
              (object) ex.GetType().FullName
            },
            {
              "exception.message",
              (object) ex.Message
            }
          };
          tags.Add("exception.stacktrace", (object) ex.StackTrace);
          ActivityEvent e = new ActivityEvent("exception", tags: tags);
          ((Activity) activity).AddEvent(e);
          ((Activity) activity).SetTag("otel.status_description", (object) ex.Message);
        }
        ((Activity) activity).SetTag("otel.status_code", (object) "ERROR");
        ((Activity) activity).Dispose();
      }
      catch
      {
      }
    }

    internal void SetNullToCurrentActivity() => Activity.Current = (Activity) null;

    internal static class SemanticConventions
    {
      public const string DB_SYSTEM_NAME = "oracle";
      public const string SOURCE_NAME = "ODPNET";
      public const string DB_SYSTEM = "db.system";
      public const string DB_NAME = "db.name";
      public const string DB_CONNECTIONSTRING = "db.connection_string";
      public const string DB_USER = "db.user";
      public const string DB_STATEMENT = "db.statement";
      public const string OTEL_STATUS_CODE = "otel.status_code";
      public const string OTEL_DESCRIPTION = "otel.status_description";
      public const string OK = "OK";
      public const string ERROR = "ERROR";
      public const string EXCEPTION_TYPE = "exception.type";
      public const string EXCEPTION_MESSAGE = "exception.message";
      public const string EXCEPTION_STACKTRACE = "exception.stacktrace";
      public const string EXCEPTION = "exception";
    }
  }
}

From Oracle.ManagedDataAccess.OpenTelemetry

using OpenTelemetry.Trace;
using Oracle.ManagedDataAccess.Client;
using System;

namespace Oracle.ManagedDataAccess.OpenTelemetry
{
  public static class TracerProviderBuilderExtensions
  {
    public static TracerProviderBuilder AddOracleDataProviderInstrumentation(
      this TracerProviderBuilder builder,
      Action<OracleDataProviderInstrumentationOptions> configureInstrumentationOptions = null)
    {
      OracleDataProviderInstrumentationOptions instrumentationOptions = new OracleDataProviderInstrumentationOptions();
      if (configureInstrumentationOptions != null)
        configureInstrumentationOptions(instrumentationOptions);
      OracleActivitySource oracleActivitySource = new OracleActivitySource();
      oracleActivitySource.EnableConnectionLevelAttributes = instrumentationOptions.EnableConnectionLevelAttributes;
      oracleActivitySource.SetDbStatementForStoredProcedure = instrumentationOptions.SetDbStatementForStoredProcedure;
      oracleActivitySource.SetDbStatementForText = instrumentationOptions.SetDbStatementForText;
      oracleActivitySource.RecordException = instrumentationOptions.RecordException;
      oracleActivitySource.InstrumentOracleDataReaderRead = instrumentationOptions.InstrumentOracleDataReaderRead;
      oracleActivitySource.RequireApplicationRootSpanCreation = instrumentationOptions.RequireApplicationRootSpanCreation;
      oracleActivitySource.EnableDBRoundTripTracing = instrumentationOptions.EnableDBRoundTripTracing;
      oracleActivitySource.EnableOpenCloseTracing = instrumentationOptions.EnableOpenCloseTracing;
      OracleCommand.IsOpenTelemetryEnabled = true;
      OracleCommand.OracleActivitySource = oracleActivitySource;
      builder.AddSource("ODPNET");
      return builder;
    }
  }
}

Please consider following changes:

  1. [ActivitySource](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.activitysource?view=net-8.0) is designed in this way that it will create activity only if there is a listener for the activity. Otherwise it will return a null. Based on this you can make more expensive extensions and add additional attributes/tags.
    Based on this, consider to always creating ActivitySource in Oracle.ManagedDataAccess and fully remove IsOpenTelemetryEnabled property.
  2. ActivitySource name is now ODPNET. From my perspective it is not so obvious. Consider make it equal to you library name: Oracle.ManagedDataAccess.
  3. You should be able to remove otel.status_code and otel.status_description - ref Support Status and StatusDescription from Activity class opentelemetry-dotnet#2569. There are better properties to track this. Keep in mind that the OK status should not be manually set. Keeping Unset if preferred solution.
  4. Please check what you can do with other recommended attributes from https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md
  5. I think that Oracle.ManagedDataAccess.OpenTelemetry package can be still useful as an optional option to configure your instrumentation (setting options) and registering AcitivitySource name in the OpenTelemetry. Based scenario without reference to this, and only calling ``TracerProviderBuilder.AddSource("Oracle.ManagedDataAccess")` should be supported.

Based on your answers, we can update documentation/add support for Oracle db in AutomaticInstrumentation.
In the current state, it sill can implemented in autoinstrumentation, but probably using some "dark magic" aka reflection. To avoid direct dependency on Oracle databases.

BTW Based on this: https://opentelemetry.devstats.cncf.io/d/5/companies-table?orgId=1&var-period_name=Last%20month&var-metric=contributions Oracle is pretty important contributor to OpenTelemetry. You can check with @marcalff how to achieve contributor status.

@alexkeh
Copy link
Author

alexkeh commented Dec 18, 2023

Thanks for the detailed feedback @Kielek. I will discuss these recommendations with the Oracle .NET dev team.

@Kielek
Copy link
Contributor

Kielek commented Jan 10, 2024

@alexkeh, do you have any plan to address this feedback? Or you keep current way for the implementation?

@alexkeh
Copy link
Author

alexkeh commented Jan 10, 2024

@Kielek Due to the holidays and different team members being on vacation, including myself, I haven't had a chance to discuss these recommendations with the full dev team yet.

@alexkeh
Copy link
Author

alexkeh commented Jan 12, 2024

@Kielek
I had a chance to discuss your recommendations with the ODP.NET team. Here's our action plan and feedback:

ActivitySource is designed in this way that it will create activity only if there is a listener for the activity. Otherwise it will return a null. Based on this you can make more expensive extensions and add additional attributes/tags.
Based on this, consider to always creating ActivitySource in Oracle.ManagedDataAccess and fully remove IsOpenTelemetryEnabled property.

When we developed ODP.NET OpenTelemetry we emulated API behavior in other OpenTelemetry providers, such as Microsoft SqlClient and Npgsql. Those providers don't appear to be following this recommendation. Yet, they are supported by autoinstrumentation. Is there a reason why ODP.NET specifically needs to follow this recommendation?

ActivitySource name is now ODPNET. From my perspective it is not so obvious. Consider make it equal to you library name: Oracle.ManagedDataAccess.

We plan to change the name to "ODP" for the ODP.NET Core provider, which runs in .NET (Core) and "ODPM" for the managed ODP.NET provider, which runs in .NET Framework.

You should be able to remove otel.status_code and otel.status_description - ref open-telemetry/opentelemetry-dotnet#2569. There are better properties to track this. Keep in mind that the OK status should not be manually set. Keeping Unset if preferred solution.

We're planning to add these changes.

Please check what you can do with other recommended attributes from https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md

We're planning to add these changes.

I think that Oracle.ManagedDataAccess.OpenTelemetry package can be still useful as an optional option to configure your instrumentation (setting options) and registering AcitivitySource name in the OpenTelemetry. Based scenario without reference to this, and only calling ``TracerProviderBuilder.AddSource("Oracle.ManagedDataAccess")` should be supported.

Ok.

@Kielek
Copy link
Contributor

Kielek commented Jan 15, 2024

@Kielek I had a chance to discuss your recommendations with the ODP.NET team. Here's our action plan and feedback:

ActivitySource is designed in this way that it will create activity only if there is a listener for the activity. Otherwise it will return a null. Based on this you can make more expensive extensions and add additional attributes/tags.
Based on this, consider to always creating ActivitySource in Oracle.ManagedDataAccess and fully remove IsOpenTelemetryEnabled property.

When we developed ODP.NET OpenTelemetry we emulated API behavior in other OpenTelemetry providers, such as Microsoft SqlClient and Npgsql. Those providers don't appear to be following this recommendation. Yet, they are supported by autoinstrumentation. Is there a reason why ODP.NET specifically needs to follow this recommendation?

Microsoft SqlClient instrumentation is not the best way to follow. It was developed before the OpenTelemetry was popular and it internally utilize DiagnosticListener to translate events to the Activities. It requires as to reference additional library to consume these functionality. I suppose that, int future, new versions of the libraries will be rewritten to provide native support for OTel by the ActivitySource.

Npqsql is a good example how to develop implementation for OTel native support.
It boths can be enabled by calling AddSource("Npgsql") (this project is using this approach) or by calling AddNpgsql() from additional package on the BuildTracer. Both solution brings exactly the same effects. Npgsql is not implementic any magic configuration IsOpenTelemetryEnabled. For some reasons, it is using manual check if anything is listening on the activity source. It can be easily swiched to StartMethod activity and null check. The performance should be similar as activity is only created when the listenr (OTel) is active. BTW technically, the OTel is not the only user of the ActivitySources. Other functionalities can listen on the same ActivitySource.

Npgsql-like design allow us to enable the support for the any library without needs to reference any additional library (which is bad, because brings dependencies which could make a conflicts in runtime) and without using reflection (as forcing to enable IsOpenTelemetryEnabled feature.

ActivitySource name is now ODPNET. From my perspective it is not so obvious. Consider make it equal to you library name: Oracle.ManagedDataAccess.

We plan to change the name to "ODP" for the ODP.NET Core provider, which runs in .NET (Core) and "ODPM" for the managed ODP.NET provider, which runs in .NET Framework.

My recommendation for both, it should be "Oracle.ManagedDataAccess". The language, framework can be deducted based on the resource attributes attached to the traces. See OpenTelemetry.ResourceDetectors.ProcessRuntime.


If your code is somehow publicly available, I can find some time to provide PR/code changes with the discussed feedback.

@alexkeh
Copy link
Author

alexkeh commented Jan 19, 2024

@Kielek Is the reason you advise the removal of the internal property IsOpenTelemetryEnabled to allow generating instrumentation at all times or is there another reason?

@Kielek
Copy link
Contributor

Kielek commented Jan 22, 2024

@Kielek Is the reason you advise the removal of the internal property IsOpenTelemetryEnabled to allow generating instrumentation at all times or is there another reason?

It is how the ActivitySource API is designed. Everything from the client perspective, should be to call "AddSource" to the OTel (or any other activity source listener). There should be no need to look into any internal details of the library.

As a reference please check:
From: https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/trace/extending-the-sdk#instrumentation-library

If you are writing a new library or modifying an existing library the recommendation is to use the ActivitySource API/OpenTelemetry API to emit activity/span instances directly. If a library is instrumented using the ActivitySource API then there isn't a need for a separate instrumentation library to exist. Users simply need to configure the OpenTelemetry SDK to listen to the ActivitySource used by the library by calling AddSource on the TracerProviderBuilder being configured. The following section is applicable only if you are writing an instrumentation library for something you cannot modify to emit activity/span instances directly.

And the MS official documentation:
https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs?source=recommendations#best-practices-2

To sum up,

Any library natively supporting should call

var activity = activitySource.StartActivity().

Then you should check

if (activity !-= null and activity.IsAllDataRequested)
{
    activity.SetAllExpensiveTagsHere();
}

Please let me know if it answers your doubts.

@reyang
Copy link
Member

reyang commented Jan 25, 2024

Then you should check

if (activity !-= null and activity.AllDataRequested)
{
    activity.SetAllExpensiveTagsHere();
}

+1, also check https://github.com/open-telemetry/opentelemetry-dotnet/blob/0a77cc3cced0be0a24dd54cd4707cf71c2b97314/src/OpenTelemetry.Api/README.md?plain=1#L210-L222

@Kielek
Copy link
Contributor

Kielek commented Feb 6, 2024

@alexkeh, do you have any progress in Oracle instrumentation?

@alexkeh
Copy link
Author

alexkeh commented Feb 9, 2024

@Kielek We plan to release a new ODP.NET OpenTelemetry version this month. It will include some of the changes you recommend.

@pjanotti pjanotti added this to the 1.5.0 milestone Feb 21, 2024
@alexkeh
Copy link
Author

alexkeh commented Mar 14, 2024

@Kielek Oracle released a new ODP.NET OpenTelemetry provider this week. We've implemented all of the suggestions you made in December. Thanks for evaluating our previous release and supplying the detailed feedback.

Is there anything else recommended to enable automatic instrumentation?

@pfdsilva
Copy link

pfdsilva commented Mar 14, 2024

Hi @Kielek
I work in the ODP.NET team along with @alexkeh .

We wanted some clarification from you regarding the following statement that you mentioned in one of your posts above.

Based on your answers, we can update documentation/add support for Oracle db in AutomaticInstrumentation.

From what we understand, what we have done for ODP.NET’s support for open telemetry is manual instrumentation as we have manually instrumented our code using System.Diagnostics API’s.

Here is a link which describes about open telemetry automatic instrumentation.

From what is mentioned in above link, I don’t think what ODP.NET is done can be classified as automatic instrumentation.

Please could you clarify if my understanding is correct?

@Kielek
Copy link
Contributor

Kielek commented Mar 15, 2024

@alexkeh, @pfdsilva, based on short review I suppose that you can check your application with 1.4.0 release. You can set OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES to Oracle.ManagedDataAccess,Oracle.ManagedDataAccess.Core. It should work.

I have a plan to add support for these two ActvitySources by default. It probably happen after March 25, next week I will have very limited time to work on this.

One more important change in db semantic convention open-telemetry/semantic-conventions#769
As you are still in prerelezse mode, consider fully removing db.connection_string attribute.

@pfdsilva
Copy link

@Kielek I have a test app that uses ODP.NET's ODPC 23c provider. I was able to enable ODPC's open telemetry traces by doing the following.

  1. Add the following environment variables.

OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES=Oracle.ManagedDataAccess.Core
OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED=true

  1. Add OpenTelemetry.AutoInstrumentation nuget to the test app.

dotnet add package OpenTelemetry.AutoInstrumentation

  1. Build the test app using the following command:

dotnet build PROJECT_NAME.csproj -r <Runtime Identifier (RID)>

  1. Execute the test app from the project directory build folder using the following command:

instrument.cmd dotnet PROJECT_NAME.dll -r <Runtime Identifier (RID)>

@Kielek
Copy link
Contributor

Kielek commented Mar 27, 2024

@pfdsilva, @alexkeh,
please, check this PR #3336 with support for both Oracle.ManagedDataAccess.Core and Oracle.ManagedDataAccess.

The plan is to keep it as a draft until you release stable version of packages.

Additional feedback after testing:
2 Important:

  • please drop db.connection_string attribute as mentioned in README update: Add Oracle .NET OpenTelemetry provider #3192 (comment)
  • consider adding versions to the place where you are creating ActivitySource. Just replace new ActivitySource("Oracle.ManagedDataAccess");bynew ActivitySource("Oracle.ManagedDataAccess", "your library version here, it can be nuget package version")`. It could be beneficial for users/support to easily verify what library version is used (to verify if there is no known issues which can be fixed just by upgrade).
    1 nice to have, it will make AutoInstrumentation easier:
  • It will be great to have possibility to set-up SetDbStatementForText by environmental variable. With this support I could just remove this whole dark magic (reflection) here 9746fa3

It is great to see such progress in Oracle instrumentation. It is pretty high on our users whish list!

@pfdsilva
Copy link

@Kielek
Please could you let us know about this?

It will be great to have possibility to set-up SetDbStatementForText by environmental variable.

@Kielek
Copy link
Contributor

Kielek commented Mar 27, 2024

@Kielek Please could you let us know about this?

It will be great to have possibility to set-up SetDbStatementForText by environmental variable.

Ref 9746fa3

It allows to configure Oracle option by environmental variable. Technically we can have it here, but it should be easier (for us) to read this values eg in constructor or by IConfiguration with defaulting to Env. Vars.: Something like:

namespace Oracle.ManagedDataAccess.OpenTelemetry
{
  internal class OracleActivitySource
  {
    internal static readonly ActivitySource m_Source = new ActivitySource("Oracle.ManagedDataAccess");

    internal bool SetDbStatementForStoredProcedure { get; set; } = ReadBoolFromEnvVar(name: "OTEL_ORAC:LEMDA_SETDBSTATEMENTFORSTOREDPROCEDURE", default: true);

    internal bool SetDbStatementForText { get; set; ) = ReadBoolFromEnvVar(name: "OTEL_ORAC:LEMDA_SETDBSTATEMENTFORTEXT", default: false);

    internal bool EnableConnectionLevelAttributes { get; set; }

    internal bool InstrumentOracleDataReaderRead { get; set; }

    internal bool RecordException { get; set; }

    internal bool EnableDBRoundTripTracing { get; set; } = true;

    internal EnableOpenCloseTracing EnableOpenCloseTracing { get; set; }

    internal bool RequireApplicationRootSpanCreation { get; set; }

    internal bool AddDBInfoToDisplayName { get; set; }

    internal bool EnableSqlIdTracing { get; set; }

@Kielek Kielek modified the milestones: 1.5.0, 1.6.0 Apr 4, 2024
@pfdsilva
Copy link

pfdsilva commented Apr 16, 2024

@Kielek
Have any of the other OpenTelemetry providers implemented this? We would like to try it out.

It allows to configure Oracle option by environmental variable. Technically we can have it here, but it should be easier (for us) to read this values eg in constructor or by IConfiguration with defaulting to Env.

Does any of the other open telemetry providers support something similar?

consider adding versions to the place where you are creating ActivitySource. Just replace new ActivitySource("Oracle.ManagedDataAccess");bynew ActivitySource("Oracle.ManagedDataAccess", "your library version here, it can be nuget package version")`. It could be beneficial for users/support to easily verify what library version is used (to verify if there is no known issues which can be fixed just by upgrade).

@alexkeh
Copy link
Author

alexkeh commented Apr 16, 2024

@Kielek We plan to release a stable version of ODP.NET OpenTelemetry by the end of the week of April 29. I'll let you know the day it happens.

@Kielek
Copy link
Contributor

Kielek commented Apr 16, 2024

@Kielek Have any of the other OpenTelemetry providers implemented this? We would like to try it out.

It allows to configure Oracle option by environmental variable. Technically we can have it here, but it should be easier (for us) to read this values eg in constructor or by IConfiguration with defaulting to Env.

Does any of the other open telemetry providers support something similar?

consider adding versions to the place where you are creating ActivitySource. Just replace new ActivitySource("Oracle.ManagedDataAccess");bynew ActivitySource("Oracle.ManagedDataAccess", "your library version here, it can be nuget package version")`. It could be beneficial for users/support to easily verify what library version is used (to verify if there is no known issues which can be fixed just by upgrade).

@pfdsilva,
If we speaking, about environemtal variables - I am not aware about such support in instrumentation libraries nor in natively instrumented libraries. But Oracle can be good example. For sure, it is not mandatory, but will reduce maintanance cost on OTel AutoInstrumentation side.

Versioning - almost all instrumetnation packages in https://github.com/open-telemetry/opentelemetry-dotnet-contrib and https://github.com/open-telemetry/opentelemetry-dotnet report library version by new ActivitySource
(name, version). Few weeks ago it was even fixed by this PR open-telemetry/opentelemetry-dotnet-contrib#1624. I would strongly recommend changing it.

@alexkeh
Copy link
Author

alexkeh commented May 2, 2024

@Kielek Oracle has released its Oracle.OpenTelemetry provider to production on NuGet Gallery. The version is 23.4. Please commit your changes to the .NET OpenTelemetry libraries and update the README.

Thanks!

@Kielek
Copy link
Contributor

Kielek commented May 6, 2024

@alexkeh, #3336 is already updated.
Expected to be merged soon and release within 1.7.0.

Thank you for delivering this support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

5 participants