C# 配置NLog以使用管理标识令牌将日志写入Azure SQL server

C# 配置NLog以使用管理标识令牌将日志写入Azure SQL server,c#,azure-active-directory,azure-sql-database,nlog,azure-virtual-machine,C#,Azure Active Directory,Azure Sql Database,Nlog,Azure Virtual Machine,我正在使用NLog,并使用ADO.NET提供程序将日志消息写入数据库 我已经为我的服务器启用了托管标识,我想连接托管标识并在Azure SQL中写入日志。我在nlog配置文件中有SP 我怎样才能做到这一点? nlog配置文件中需要进行哪些更改 NLog版本:4.6.6 站台:。净核心2 需要使用Azure SQL中的托管标识记录错误 编辑- 此外,我还尝试通过代码构建databasetarget,但无法设置accesstoken。 这是投掷错误 不支持关键字:',访问令牌' 基于和Rolf指

我正在使用NLog,并使用ADO.NET提供程序将日志消息写入数据库

我已经为我的服务器启用了托管标识,我想连接托管标识并在Azure SQL中写入日志。我在nlog配置文件中有SP

我怎样才能做到这一点? nlog配置文件中需要进行哪些更改

  • NLog版本:4.6.6
  • 站台:。净核心2
  • 需要使用Azure SQL中的托管标识记录错误
编辑- 此外,我还尝试通过代码构建databasetarget,但无法设置accesstoken。 这是投掷错误

不支持关键字:',访问令牌'

基于和Rolf指示。NLog不提供使用访问令牌连接到Azure SQL DB目标的现成接口。因此,恐怕您应该在此处使用带有身份验证信息的Azure SQL连接字符串

如果您希望避免泄露带有身份验证信息的Azure SQL server连接字符串,或者希望确保只有具有MSI的服务器才能使用NLog将日志写入Azure SQL DB,那么这可能是一种解决方法:


并配置一个访问策略,以确保只有您的服务器可以访问它。当Nlog需要连接到Azure SQL时,使用服务器MSI直接从密钥库读取完整的连接字符串,以提供Nlog目标

您可以创建自己的Ado IDbConnection,该连接封装一个SqlConnection,该SqlConnection在名为MyAssembly的项目中自动分配AccessToken:

namespace MyNameSpace
{
   public class MyDbConnection : System.Data.IDbConnection
   {
      private readonly System.Data.IDbConnection _sqlConnection;

      public MyDbConnection()
      {
          var sqlConnection = new SqlConnection;
          // Could probably delay the assignment to when Open() is called
          sqlConnection.AccessToken = "Hello World";
          _sqlConnection = sqlConnection;
      }

      public string ConnectionString
      {
          get => _sqlConnection.ConnectionString;
          set => _sqlConnection.ConnectionString = value;
      }

      public int ConnectionTimeout => _sqlConnection.ConnectionTimeout;
      public string Database => _sqlConnection.Database;
      public ConnectionState State => _sqlConnection.State;
      public IDbTransaction BeginTransaction() => _sqlConnection.BeginTransaction();
      public IDbTransaction BeginTransaction(IsolationLevel il) => _sqlConnection.BeginTransaction(il);
      public void ChangeDatabase(string databaseName) => _sqlConnection.ChangeDatabase(databaseName);
      public void Close() => _sqlConnection.Close();
      public IDbCommand CreateCommand() => _sqlConnection.CreateCommand();
      public void Open() => _sqlConnection.Open();
      public void Dispose() => _sqlConnection.Dispose();
   }
}
然后告诉NLog DatabaseTarget使用MyAssembly.dll中的自定义MyDbConnection:

<target type="database" dbprovider="MyNameSpace.MyDbConnection, MyAssembly">
</target>

很抱歉出现任何编译器错误,因为我没有测试提供的代码,只是一个随机的想法


另请参见:

NLog 4.7现已发布,支持分配数据库连接属性,如AccessToken。AccessToken可以使用以下nuget包获取:


您是否尝试使用想要的标识设置连接字符串:我正在使用Azure sql存储日志,nlog文档在其文档中没有用于对标识令牌进行参数化的任何内容。NLog DatabaseTarget要求您使用ConnectionString来设置身份验证。你试过问Microsoft Azure SQL是否可以与Ado ConnectionString一起使用吗?嗨,Rolf,我可以使用System.Data.SqlClient的SqlConnection连接Azure SQL。SqlConnection支持访问\u令牌属性。类似的事情我在NLog.Targets的DatabaseTarget类中找不到。我使用的是NLog类的4.6.6版本。NLog数据库目标不是特定于Azure SQL的。因此无法直接设置
SqlConnection.acces\u token
,除非可以使用ConnectionString完成。Lol我在这里与MySql混淆;)(MySqlConnection()for SQL server?!)更新了代码,并重命名为MyDbConnection(而不是MySqlConnection)您好,如果对我的解决方案有任何不清楚的地方,请随时通知我:)
<target type="database" dbprovider="MyNameSpace.MyDbConnection, MyAssembly">
</target>
<extensions>
  <add assembly="NLog.Extensions.AzureAccessToken" /> 
</extensions>

<targets>
  <target xsi:type="Database" connectionString="...">
    <dbProvider>Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient</dbProvider>
    <connectionProperty name="AccessToken" layout="${AzureAccessToken:ResourceName=${gdc:DatabaseHostSuffix}}"  />
  </target>
</targets>
NLog.GlobalDiagnosticsContext.Set("DatabaseHostSuffix", $"https://{DatabaseHostSuffix}/");
NLog.LogManager.LoadConfiguration("nlog.config");