Nice3point.Revit.Logging 2027.0.0

Prefix Reserved
dotnet add package Nice3point.Revit.Logging --version 2027.0.0
                    
NuGet\Install-Package Nice3point.Revit.Logging -Version 2027.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nice3point.Revit.Logging" Version="2027.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nice3point.Revit.Logging" Version="2027.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Nice3point.Revit.Logging" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nice3point.Revit.Logging --version 2027.0.0
                    
#r "nuget: Nice3point.Revit.Logging, 2027.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nice3point.Revit.Logging@2027.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nice3point.Revit.Logging&version=2027.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Nice3point.Revit.Logging&version=2027.0.0
                    
Install as a Cake Tool

Logging library for Revit

Nuget Downloads Last Commit

Write logs for your Revit add-ins using Microsoft.Extensions.Logging. The library adds the journal of the Revit session as a logging destination and writes every record there as a journal comment.

Log levels, filtering, scopes and message templates are handled by Microsoft.Extensions.Logging.

Installation

You can install this library as a NuGet package.

The packages are compiled for specific versions of Revit. To support different versions of libraries in one project, use the RevitVersion property:


<PackageReference Include="Nice3point.Revit.Logging" Version="$(RevitVersion).*"/>

Writing your first record

Start by adding the provider to the host of your application:

public class Application : ExternalApplication
{
    public override void OnStartup()
    {
        var builder = Host.CreateApplicationBuilder();
        builder.Logging.AddRevitJournal(Application.ControlledApplication);

        builder.Build().Start();
    }
}

ServiceCollection works the same way when your add-in has no host:

public class Application : ExternalApplication
{
    public override void OnStartup()
    {
        var services = new ServiceCollection();
        services.AddLogging(logging => logging.AddRevitJournal(Application.ControlledApplication));

        var serviceProvider = services.BuildServiceProvider();
    }
}

Inject ILogger<T> and write a record:

public class UpdateService(ILogger<UpdateService> logger)
{
    public void CheckUpdates()
    {
        logger.LogInformation("Checking updates");
    }
}

The record appears in the journal of the running session:

'C 05-Sep-2026 22:48:59.703;   0:< RevitAddin_INFORMATION { RevitAddin.Services.UpdateService: Checking updates }

Revit stores journals in %LocalAppData%\Autodesk\Revit\Autodesk Revit {version}\Journals.

Record format

The library writes the record, Revit writes the beginning of the line:

' 0:< RevitAddin_WARNING { RevitAddin.Services.SettingsService: Settings file is missing }
'C 05-Sep-2026 22:48:59.703;   0:< RevitAddin_ERROR { RevitAddin.Services.UpdateService: Update service error }

A record has the following format:

{ApplicationName}_{Level} { {Category}[{EventId}] => {Scope} => {Scope}: {Message}
{Exception} }

The braces bound the record. An exception occupies the lines that follow the message, and Revit opens each of them with an apostrophe:

' 0:< RevitAddin_ERROR { RevitAddin.Services.UpdateService: Update service error
'System.Net.Http.HttpRequestException: Response status code does not indicate success: 403.
'   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() }

Text you log needs no escaping. Revit comments out every line of a record, including a line that contains a journal command.

Log levels

The provider alias is RevitJournal. Set the minimum level for the journal separately from the other providers:

{
    "Logging": {
        "LogLevel": {
            "Default": "Information"
        },
        "RevitJournal": {
            "LogLevel": {
                "Default": "Error"
            }
        }
    }
}

The same filter in code:

builder.Logging.AddFilter<RevitJournalLoggerProvider>(null, LogLevel.Error);

A journal keeps the whole session and the user sends it to Autodesk with an error report. Keep the minimum level at Warning or Error in a release build.

Options

Option Default Description
ApplicationName Name of the assembly that called AddRevitJournal Opens the record token and identifies your add-in in a journal
IncludeCategory true Writes the category of the record
IncludeEventId false Writes the event id in square brackets after the category
IncludeScopes false Writes the scopes of the record, joined by =>
IncludeTimestamp true Opens the journal line with the time stamp of the session
SingleLine false Collapses the line breaks of the message and of the exception

Configure them when you add the provider:

builder.Logging.AddRevitJournal(Application.ControlledApplication, options =>
{
    options.ApplicationName = "RevitAddin";
    options.IncludeScopes = true;
});

Options also bind from the Logging:RevitJournal section:

{
    "Logging": {
        "RevitJournal": {
            "IncludeScopes": true,
            "IncludeEventId": true
        }
    }
}

Configuration is applied first, and the options delegate overrides it.

IncludeTimestamp

Revit writes the time stamp in the format the rest of the journal uses:

'C 05-Sep-2026 22:48:59.703;   0:< RevitAddin_ERROR { ... }

Turn it off to shorten the line. The nearest stamped line above then dates the record:

' 0:< RevitAddin_ERROR { ... }

Scopes

IncludeScopes writes the scopes of the record, from the outermost one:

using (logger.BeginScope("Startup"))
using (logger.BeginScope("Document {Title}", document.Title))
{
    logger.LogError("Update service error");
}
' 0:< RevitAddin_ERROR { RevitAddin.Services.UpdateService => Startup => Document Snowdon Towers: Update service error }

Multithreading

A record is written on the thread that logged it, both inside and outside the Revit API context. Wrap nothing in an external event and marshal nothing onto the Revit thread:

await Task.Run(() =>
{
    logger.LogError("Update service error");
});

Revit serializes the writes, and records never mix with each other.

Custom formatter

Inherit RevitJournalFormatter to write your own record format:

public class MessageOnlyFormatter : RevitJournalFormatter
{
    public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider? scopeProvider, StringBuilder record)
    {
        record.Append(logEntry.LogLevel)
            .Append(' ')
            .Append(logEntry.Formatter(logEntry.State, logEntry.Exception));
    }
}

Register it after the provider:

builder.Logging.AddRevitJournal(Application.ControlledApplication);
builder.Logging.AddRevitJournalFormatter<MessageOnlyFormatter>();

The record buffer is empty on entry and reused between records. Leave it empty to discard a record.

Product Compatible and additional computed target framework versions.
.NET net10.0-windows7.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2027.0.0 72 9/5/2026
2026.0.0 62 9/5/2026
2025.0.0 60 9/5/2026
2024.0.0 63 9/5/2026
2023.0.0 64 9/5/2026
2022.0.0 57 9/5/2026
2021.0.0 58 9/5/2026
2020.0.0 57 9/5/2026