Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The App will provide a default logger, but you can also provide your own.
The default Logger instance will be set to ConsoleLogger from the Microsoft.Teams.Common package.
The App will provide a default logger, but you can also provide your own.
The default Logger instance will be set to Python's standard logging module, using logging.getLogger(__name__) per module. from the microsoft-teams-common package.
The App will provide a default logger, but you can also provide your own.
The default Logger instance will be set to ConsoleLogger from the @microsoft/teams.common package.
using Microsoft.Teams.Apps;
using Microsoft.Teams.Common.Logging;
using Microsoft.Teams.Plugins.AspNetCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
var appBuilder = App.Builder()
.AddLogger(new ConsoleLogger())
builder.AddTeams(appBuilder)
var app = builder.Build();
var teams = app.UseTeams();
The Python SDK uses standard logging — there's no custom logger to inject into App. To see SDK log output, attach a handler to the microsoft_teams logger hierarchy. The SDK ships a ConsoleFormatter with color-coded output if you want it:
import logging
import os
from microsoft_teams.common import ConsoleFormatter
handler = logging.StreamHandler()
handler.setFormatter(ConsoleFormatter())
logging.getLogger("microsoft_teams").addHandler(handler)
logging.getLogger("microsoft_teams").setLevel(
os.getenv("LOG_LEVEL", "INFO").upper()
)
import { App } from '@microsoft/teams.apps';
import { ConsoleLogger } from '@microsoft/teams.common';
// initialize app with custom console logger
// set to debug log level
const app = new App({
logger: new ConsoleLogger('echo', { level: 'debug' }),
});
app.on('message', async ({ send, activity, log }) => {
log.debug(activity);
await send({ type: 'typing' });
await send(`you said "${activity.text}"`);
});
(async () => {
await app.start();
})();
Log Levels
Python's standard logging levels apply: DEBUG, INFO, WARNING, ERROR, CRITICAL.
Available levels, from most to least severe: error, warn, info, debug, trace. The default is info. Setting level: 'debug' emits error, warn, info, and debug — but not trace.
Filtering by Logger Name
Each logger is created with a name. You can filter which loggers emit output by providing a name pattern, using * as a wildcard.
Use ConsoleFilter to limit which loggers emit, matched by name with * wildcards:
from microsoft_teams.common import ConsoleFilter, ConsoleFormatter
handler = logging.StreamHandler()
handler.setFormatter(ConsoleFormatter())
handler.addFilter(ConsoleFilter("microsoft_teams*")) # only SDK loggers
logging.getLogger().addHandler(handler)
Each logger has a name. The pattern option filters which loggers emit, with * as a wildcard. Prefix a pattern with - to exclude. Combine with commas.
new ConsoleLogger('my-app', { pattern: '@teams*' }); // only SDK loggers
new ConsoleLogger('my-app', { pattern: '*,-@teams/http*' }); // everything except HTTP
Environment Variables
The Python SDK does not read logging environment variables on its own. If you want LOG_LEVEL to control verbosity, read it yourself at startup:
import os
logging.getLogger().setLevel(os.getenv("LOG_LEVEL", "INFO").upper())
The TypeScript SDK's ConsoleLogger reads two environment variables at construction:
| Variable | Purpose | Example |
|---|---|---|
LOG_LEVEL |
Minimum severity | LOG_LEVEL=debug |
LOG |
Logger name pattern (wildcards) | LOG=@teams* |
Env vars override options passed to the constructor. If you do not pass a logger to App, the SDK creates a default ConsoleLogger named @teams/app — so LOG_LEVEL=debug alone is enough to enable debug output.
Gotcha:
LOGis a name filter, not a toggle. SettingLOGto a pattern that doesn't match the default@teams/app(for exampleLOG=my-app*) silences the default logger. If in doubt, unsetLOGto match everything.
Child Loggers
Call log.child('scope') on an existing logger to get a scoped logger. Its name is parent/scope, and pattern/level are inherited.
app.on('message', async ({ log }) => {
const msgLog = log.child('message-handler');
msgLog.debug('processing'); // logged as "@teams/app/message-handler"
});