You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NLog MongoDB配置中动态指定集合名与运行时修改数据库名

Alright, let's break down how to solve both of your requirements for NLog's MongoDB target. I've worked through similar scenarios before, so here's a practical approach:

Solution for Dynamic Collection Name and Runtime Database Name in NLog MongoDB

1. Using a Variable for collectionName

NLog lets you use layout renderers or configuration variables to make collectionName dynamic. This is straightforward since the Mongo target supports layout values for this property.

Option 1: Use a Configuration Variable

Define a variable in your NLog config, then reference it in the target:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd" autoReload="true" throwExceptions="true">
  <!-- Define your collection name variable -->
  <variable name="LogCollection" value="DefaultLogDocument" />

  <extensions>
    <add assembly="NLog.Mongo" />
  </extensions>

  <targets async="true">
    <target xsi:type="Mongo" 
            name="mongoCustom" 
            includeDefaults="false" 
            connectionString="mongodb://mongodb0.example.com:27017" 
            databaseName="logDb" 
            <!-- Reference the variable here -->
            collectionName="${var:LogCollection}" 
            cappedCollectionSize="26214400">
      <field name="Date" layout="${longdate}" bsonType="DateTime" />
      <field name="Level" layout="${level}"/>
      <field name="Message" layout="${message}" />
      <field name="Logger" layout="${logger}"/>
      <field name="Location" layout="${callsite:className=true:methodName=true}" />
      <field name="Exception" layout="${exception:format=tostring}" />
      <field name="ThreadId" layout="${threadid}" bsonType="Int32" />
      <field name="ThreadName" layout="${threadname}" />
      <field name="ProcessId" layout="${processid}" bsonType="Int32" />
      <field name="ProcessName" layout="${processname:fullName=true}" />
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Warn" writeTo="mongoCustom" />
  </rules>
</nlog>

Option 2: Dynamic Collection Name (e.g., Date-Based)

For more flexibility, you can use a layout renderer directly to generate collection names on the fly (like daily collections):

collectionName="Log_${date:format=yyyyMMdd}"

This creates a new collection each day (e.g., Log_20240520).

2. Dynamically Change databaseName at Runtime

Unlike collectionName, databaseName isn't always layout-compatible in older NLog.Mongo versions. The most reliable way is to update the target's property directly in code and reconfigure NLog.

Step 1: Update the Target in Code

Since your target is wrapped in an AsyncTargetWrapper, you'll need to access the underlying MongoTarget first:

// Get the async wrapper target
var asyncWrapper = LogManager.Configuration.FindTargetByName<AsyncTargetWrapper>("mongoCustom");
// Extract the actual Mongo target from the wrapper
var mongoTarget = asyncWrapper.WrappedTarget as MongoTarget;

if (mongoTarget != null)
{
    // Update to your desired database name
    mongoTarget.DatabaseName = "newLogDb";
    // Apply changes to all existing loggers
    LogManager.ReconfigExistingLoggers();
}

If your target isn't async, skip the wrapper step:

var mongoTarget = LogManager.Configuration.FindTargetByName<MongoTarget>("mongoCustom");
if (mongoTarget != null)
{
    mongoTarget.DatabaseName = "newLogDb";
    LogManager.ReconfigExistingLoggers();
}

Option 2: Per-Context Database Name (Advanced)

If you need to switch databases based on request or logical context, use NLog's Mapped Diagnostics Logical Context (MDLC) (requires a recent NLog.Mongo version that supports layout for databaseName):

  1. Update the config to use MDLC:
databaseName="${mdlc:item=CurrentDatabase:default=logDb}"
  1. Set the database name in your code when needed (e.g., at the start of a request):
// Assign database name for the current logical context
MappedDiagnosticsLogicalContext.Set("CurrentDatabase", "userSpecificDb");

This routes logs to the specified database for all events in that context (works seamlessly with async/await).

Key Notes

  • Ensure you're using a recent version of NLog.Mongo to support these features.
  • If autoReload="true" is enabled, config file changes will override code-based updates—adjust this setting if needed.
  • Always call LogManager.ReconfigExistingLoggers() after modifying target properties to apply changes immediately.

内容的提问来源于stack exchange,提问作者Mico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 21:52:31