The Spanner client libraries contain a relatively rudimentary
logging mechanism for diagnostic purposes. It is not intended for
general application use, and most applications will never need to
take any of the steps shown on this page. This page is primarily
intended to make it easier for Google Cloud support
engineers to help you configure your application to add logging if
you encounter an issue.
The exact log entries generated are subject to change, and
applications should not rely on particular messages.
Both the Logger and LogLevel types decribed below are in the
Google.Cloud.Spanner.V1.Internal.Logging namespace.
Log levels
The Logger.LogLevel property determines which log events are
actually recorded. By default, this is LogLevel.None, so there is
no output.
If you're happy using the default logger implementation described
below, and just need to change the log level, you can write code
like this:
// Adjust for the desired log level
Logger.DefaultLogger.LogLevel = LogLevel.Info;
This can be performed at any time, and the default logger will start
using the given log level.
The default logger implementation
The default logger implementation writes to one of two places based
on the DLL being targeted:
In the .NET Standard 1.5 DLL, it writes to Console.Error
In the .NET Standard 2.0 and .NET Framework 4.5 DLLs, it calls
Trace.TraceInformation,
regardless of the log level of the event.
The exact DLL being used will depend on multiple factors in your
application's build. As a general rule, if you're using .NET Core
2.0 or above, or any version of the .NET Framework, you'll probably
be using a DLL that uses Trace.TraceInformation.
Writing a custom logger
If you need the log output in some different form, you can create
your own class deriving from Logger. You need to implement two
methods:
LogPerformanceEntries to log performance information. If you
aren't performing performance tests, you can use an empty
implementation.
LogImpl to log a single message with an optional exception. This
is only called by Logger if the log level equals or exceeds the
LogLevel of the logger, so the implementation can simply write
the message/exception where it needs to.
Once you have implemented a logger, you'll need to configure the
Spanner library to use it. If you're using the default
SessionPoolManager, this is simply a matter of calling:
// Replace with whatever your implementation is called, or
// however it is instantiated.
Logger logger = new MyCustomLogger();
Logger.SetDefaultLogger(logger);
This must be performed before any other Spanner operations, as
otherwise the default SessionPoolManager will be created with the
original default logger implementation.
If you are creating a new SessionPoolManager instance, simply pass
the logger to the SessionPoolManager.Create method:
SessionPoolOptions options = new SessionPoolOptions
{
// Custom options here
};
// Replace with whatever your implementation is called, or
// however it is instantiated.
Logger logger = new MyCustomLogger();
SessionPoolManager poolManager = SessionPoolManager.Create(options, logger);
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-07 UTC."],[[["\u003cp\u003eThe latest version available for the Google Cloud Spanner Data library is 5.0.0-beta05, with multiple previous versions also accessible.\u003c/p\u003e\n"],["\u003cp\u003eThe Spanner client libraries have a logging mechanism for diagnostic purposes, primarily for Google Cloud support engineers, not intended for general application use.\u003c/p\u003e\n"],["\u003cp\u003eBy default, the logger's output is set to \u003ccode\u003eLogLevel.None\u003c/code\u003e, resulting in no logging output, but this can be modified to log events based on the desired log level.\u003c/p\u003e\n"],["\u003cp\u003eThe default logger implementation writes to \u003ccode\u003eConsole.Error\u003c/code\u003e for .NET Standard 1.5 DLLs and uses \u003ccode\u003eTrace.TraceInformation\u003c/code\u003e for .NET Standard 2.0 and .NET Framework 4.5 DLLs.\u003c/p\u003e\n"],["\u003cp\u003eCustom loggers can be created by deriving from the \u003ccode\u003eLogger\u003c/code\u003e class and implementing \u003ccode\u003eLogPerformanceEntries\u003c/code\u003e and \u003ccode\u003eLogImpl\u003c/code\u003e, which then needs to be set as default before other spanner operations, or passed through the \u003ccode\u003eSessionPoolManager\u003c/code\u003e creation.\u003c/p\u003e\n"]]],[],null,["Version latestkeyboard_arrow_down\n\n- [5.1.0 (latest)](/dotnet/docs/reference/Google.Cloud.Spanner.Data/latest/logging)\n- [5.0.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/5.0.0/logging)\n- [4.6.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.6.0/logging)\n- [4.5.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.5.0/logging)\n- [4.4.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.4.0/logging)\n- [4.3.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.3.0/logging)\n- [4.2.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.2.0/logging)\n- [4.1.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.1.0/logging)\n- [4.0.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/4.0.0/logging)\n- [3.15.1](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.15.1/logging)\n- [3.14.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.14.0/logging)\n- [3.13.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.13.0/logging)\n- [3.12.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.12.0/logging)\n- [3.11.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.11.0/logging)\n- [3.10.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.10.0/logging)\n- [3.9.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.9.0/logging)\n- [3.8.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.8.0/logging)\n- [3.7.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.7.0/logging)\n- [3.6.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.6.0/logging)\n- [3.5.0](/dotnet/docs/reference/Google.Cloud.Spanner.Data/3.5.0/logging) \n\nLogging\n=======\n\nThe Spanner client libraries contain a relatively rudimentary\nlogging mechanism for diagnostic purposes. It is not intended for\ngeneral application use, and most applications will never need to\ntake any of the steps shown on this page. This page is primarily\nintended to make it easier for Google Cloud support\nengineers to help you configure your application to add logging if\nyou encounter an issue.\n\nThe exact log entries generated are subject to change, and\napplications should not rely on particular messages.\n\nBoth the `Logger` and `LogLevel` types decribed below are in the\n`Google.Cloud.Spanner.V1.Internal.Logging` namespace.\n\nLog levels\n----------\n\nThe `Logger.LogLevel` property determines which log events are\nactually recorded. By default, this is `LogLevel.None`, so there is\nno output.\n\nIf you're happy using the default logger implementation described\nbelow, and just need to change the log level, you can write code\nlike this: \n\n // Adjust for the desired log level\n Logger.DefaultLogger.LogLevel = LogLevel.Info;\n\nThis can be performed at any time, and the default logger will start\nusing the given log level.\n\nThe default logger implementation\n---------------------------------\n\nThe default logger implementation writes to one of two places based\non the DLL being targeted:\n\n- In the .NET Standard 1.5 DLL, it writes to `Console.Error`\n- In the .NET Standard 2.0 and .NET Framework 4.5 DLLs, it calls [`Trace.TraceInformation`](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.trace.traceinformation?view=netframework-4.7.2), regardless of the log level of the event.\n\nThe exact DLL being used will depend on multiple factors in your\napplication's build. As a general rule, if you're using .NET Core\n2.0 or above, or any version of the .NET Framework, you'll probably\nbe using a DLL that uses `Trace.TraceInformation`.\n\nWriting a custom logger\n-----------------------\n\nIf you need the log output in some different form, you can create\nyour own class deriving from `Logger`. You need to implement two\nmethods:\n\n- `LogPerformanceEntries` to log performance information. If you aren't performing performance tests, you can use an empty implementation.\n- `LogImpl` to log a single message with an optional exception. This is only called by `Logger` if the log level equals or exceeds the `LogLevel` of the logger, so the implementation can simply write the message/exception where it needs to.\n\nOnce you have implemented a logger, you'll need to configure the\nSpanner library to use it. If you're using the default\n`SessionPoolManager`, this is simply a matter of calling: \n\n // Replace with whatever your implementation is called, or\n // however it is instantiated.\n Logger logger = new MyCustomLogger();\n Logger.SetDefaultLogger(logger);\n\nThis must be performed before *any* other Spanner operations, as\notherwise the default `SessionPoolManager` will be created with the\noriginal default logger implementation.\n\nIf you are creating a new `SessionPoolManager` instance, simply pass\nthe logger to the `SessionPoolManager.Create` method: \n\n SessionPoolOptions options = new SessionPoolOptions\n {\n // Custom options here\n };\n // Replace with whatever your implementation is called, or\n // however it is instantiated.\n Logger logger = new MyCustomLogger();\n\n SessionPoolManager poolManager = SessionPoolManager.Create(options, logger);"]]