Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
09cc182
feat: deprecate LogLevel.default and .error and remove all calls to t…
MarioJGMsoft Apr 27, 2026
3525674
feat: send LogLevel as undefined and default to essential on send logic
MarioJGMsoft Apr 27, 2026
f3c37bf
Merge branch 'main' into marioja/deprecateLogLevel
MarioJGMsoft Apr 28, 2026
07925f4
Merge branch 'microsoft:main' into marioja/deprecateLogLevel
MarioJGMsoft Apr 29, 2026
67614c8
refactor: properly ordered imports and removed LogLevel.default
MarioJGMsoft Apr 29, 2026
a568d12
docs: fixed comments
MarioJGMsoft Apr 29, 2026
9a81682
docs: updated docs
MarioJGMsoft Apr 29, 2026
da948a1
docs: added changesets
MarioJGMsoft Apr 29, 2026
c0d9396
docs: added removal timeline
MarioJGMsoft Apr 29, 2026
f3a92b6
docs: updated deprecation message
MarioJGMsoft Apr 29, 2026
0ba1037
docs: addressed docs comments
MarioJGMsoft May 4, 2026
eab130c
Merge branch 'microsoft:main' into marioja/deprecateLogLevel
MarioJGMsoft May 5, 2026
5f1205d
docs: updated chengeset title
MarioJGMsoft May 5, 2026
ba39358
feat: applied changes to docs and code based on comments
MarioJGMsoft May 5, 2026
bad5774
feat: made logLevel required in various levels and added tests
MarioJGMsoft May 6, 2026
71c1f07
fix: removed type import from normal import
MarioJGMsoft May 6, 2026
2c13181
fix: applied changes based on review
MarioJGMsoft May 6, 2026
3b3f5fe
docs: updated docs
MarioJGMsoft May 6, 2026
fbd560a
docs: removed changeset
MarioJGMsoft May 6, 2026
5d5fcb1
docs: updated performance docs
MarioJGMsoft May 6, 2026
beeac4c
Merge branch 'main' into marioja/deprecateLogLevel
MarioJGMsoft May 6, 2026
bee89e1
chore: untrack dev-container bind-mounted files accidentally added
MarioJGMsoft May 6, 2026
1131b62
docs: updated docs message
MarioJGMsoft May 6, 2026
1205a20
feat: applied changes based on comments
MarioJGMsoft May 7, 2026
c033d8a
Merge branch 'main' into marioja/deprecateLogLevel
MarioJGMsoft May 7, 2026
03adcc4
feat: updated guidance and returned childLogger--Sink tests
MarioJGMsoft May 7, 2026
389760d
Merge branch 'main' into marioja/deprecateLogLevel
MarioJGMsoft May 8, 2026
ece6302
docs: updated docs
MarioJGMsoft May 8, 2026
24984f4
docs: applied changes based on comments
MarioJGMsoft May 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/salty-colts-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@fluidframework/core-interfaces": minor
"__section": deprecation
---

Deprecated LogLevel.default and LogLevel.error
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Deprecated LogLevel.default and LogLevel.error
Deprecate LogLevel.default and LogLevel.error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied change


`LogLevel.default` and `LogLevel.error` in `@fluidframework/core-interfaces` are deprecated in favor of the semantically clearer `LogLevel.info` and `LogLevel.essential`.

#### Migration

The recommended replacement for `LogLevel.default` depends on how the value is used:

- For an **event's default `logLevel`** (e.g. the `logLevel` argument to `sendTelemetryEvent` / `sendPerformanceEvent` / `ITelemetryBaseLogger.send`), the recommendation is `LogLevel.essential`.

Check failure on line 14 in .changeset/salty-colts-appear.md

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [Microsoft.Foreign] Use 'for example' instead of 'e.g. '. Raw Output: {"message": "[Microsoft.Foreign] Use 'for example' instead of 'e.g. '.", "location": {"path": ".changeset/salty-colts-appear.md", "range": {"start": {"line": 14, "column": 42}}}, "severity": "ERROR"}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little funny because we don't want anyone implementing sendTelemetryEvent / sendPerformanceEvent. Just ITelemetryBaseLogger.send will do.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied change

- For a logger's **default `minLogLevel`** (the threshold that filters events), `LogLevel.info` is the recommendation.

The replacement for `LogLevel.error` should always be essential.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"essential" -> "LogLevel.essential" so the replacement is symmetric with the source.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied change


See [issue #26969](https://github.com/microsoft/FluidFramework/issues/26969) for full guidance and removal tracking (planned for v3.0).
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

// @public
export interface LogLevelConst {
// @deprecated
readonly default: 20;
// @deprecated
readonly error: 30;
readonly essential: 30;
readonly info: 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,9 @@ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

// @public
export interface LogLevelConst {
// @deprecated
readonly default: 20;
// @deprecated
readonly error: 30;
readonly essential: 30;
readonly info: 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

// @public
export interface LogLevelConst {
// @deprecated
readonly default: 20;
// @deprecated
readonly error: 30;
readonly essential: 30;
readonly info: 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

// @public
export interface LogLevelConst {
// @deprecated
readonly default: 20;
// @deprecated
readonly error: 30;
readonly essential: 30;
readonly info: 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];

// @public
export interface LogLevelConst {
// @deprecated
readonly default: 20;
// @deprecated
readonly error: 30;
readonly essential: 30;
readonly info: 20;
Expand Down
10 changes: 6 additions & 4 deletions packages/common/core-interfaces/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ export interface LogLevelConst {

/**
* Default LogLevel
* @remarks Prefer {@link LogLevelConst.info | LogLevel.info} when selecting a level explicitly since this will be deprecated and removed in a future release.
* @deprecated Prefer {@link LogLevelConst.info | LogLevel.info} when selecting a level explicitly to preserve prior treatment. Planned to be removed in 3.0.0.
* @see {@link https://github.com/microsoft/FluidFramework/issues/26969 | Issue #26969} for removal tracking.
*/
readonly default: 20;

/**
* To log errors.
* @remarks Prefer {@link LogLevelConst.essential | LogLevel.essential} when selecting a level since this will be deprecated and removed in a future release.
* @deprecated Prefer {@link LogLevelConst.essential | LogLevel.essential} when selecting a level. Planned to be removed in 3.0.0.
* @see {@link https://github.com/microsoft/FluidFramework/issues/26969 | Issue #26969} for removal tracking.
*/
readonly error: 30;
}
Expand Down Expand Up @@ -120,13 +122,13 @@ export interface ITelemetryBaseLogger {
/**
* Log a telemetry event, if it meets the appropriate log-level threshold (see {@link ITelemetryBaseLogger.minLogLevel}).
* @param event - The event to log.
* @param logLevel - The log level of the event. Default: {@link LogLevelConst.default | LogLevel.default}.
* @param logLevel - The log level of the event. If undefined, the logLevel should be treated as {@link LogLevelConst.essential | LogLevel.essential}.
*/
send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void;

/**
* Minimum log level to be logged.
* @defaultValue {@link LogLevelConst.default | LogLevel.default}.
* @defaultValue {@link LogLevelConst.info | LogLevel.info}.
*/
minLogLevel?: LogLevel;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/loader/container-loader/src/test/container.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
TypedEventEmitter,
type IProvideLayerCompatDetails,
} from "@fluid-internal/client-utils";
import { AttachState, type IAudience } from "@fluidframework/container-definitions";
Comment thread
jason-ha marked this conversation as resolved.
import type { IAudience } from "@fluidframework/container-definitions";
import { AttachState } from "@fluidframework/container-definitions";
import type {
ICriticalContainerError,
IContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export interface ITelemetryLoggerExt extends ITelemetryBaseLogger {
// @deprecated
sendErrorEvent(event: ITelemetryErrorEventExt, error?: unknown): void;
// @deprecated
sendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.default): void;
sendPerformanceEvent(event: ITelemetryPerformanceEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.info): void;
// @deprecated
sendTelemetryEvent(event: ITelemetryGenericEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.default): void;
sendTelemetryEvent(event: ITelemetryGenericEventExt, error?: unknown, logLevel?: typeof LogLevel.verbose | typeof LogLevel.info): void;
}

// @beta @legacy (undocumented)
Expand Down
53 changes: 28 additions & 25 deletions packages/utils/telemetry-utils/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,18 +224,18 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
*
* @param event - the event to send
* @param error - optional error object to log
* @param logLevel - optional level of the log. It category of event is set as error,
* then the logLevel will be upgraded to be an error.
* @param logLevel - optional level of the log. If the event's category is `error`,
* the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
*/
public sendTelemetryEvent(
event: ITelemetryGenericEventExt,
error?: unknown,
logLevel: typeof LogLevel.verbose | typeof LogLevel.default = LogLevel.default,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
): void {
this.sendTelemetryEventCore(
{ ...event, category: event.category ?? "generic" },
error,
event.category === "error" ? LogLevel.error : logLevel,
event.category === "error" ? LogLevel.essential : (logLevel ?? LogLevel.essential),
);
}

Expand All @@ -244,12 +244,12 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
*
* @param event - the event to send
* @param error - optional error object to log
* @param logLevel - optional level of the log.
* @param logLevel - level of the log.
*/
protected sendTelemetryEventCore(
private sendTelemetryEventCore(
event: ITelemetryGenericEventExt & { category: TelemetryEventCategory },
error?: unknown,
logLevel?: LogLevel,
error: unknown,
logLevel: LogLevel,
): void {
const newEvent = convertToBaseEvent(event);
if (error !== undefined) {
Expand Down Expand Up @@ -280,7 +280,7 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
category: "error",
},
error,
LogLevel.error,
LogLevel.essential,
);
}

Expand All @@ -289,13 +289,13 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
*
* @param event - Event to send
* @param error - optional error object to log
* @param logLevel - optional level of the log. It category of event is set as error,
* then the logLevel will be upgraded to be an error.
* @param logLevel - optional level of the log. If the event's category is `error`,
* the logLevel will be upgraded to {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential}.
*/
public sendPerformanceEvent(
event: ITelemetryPerformanceEventExt,
error?: unknown,
logLevel: typeof LogLevel.verbose | typeof LogLevel.default = LogLevel.default,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
): void {
const perfEvent = {
...event,
Expand All @@ -305,7 +305,7 @@ export abstract class TelemetryLogger implements TelemetryLoggerExt {
this.sendTelemetryEventCore(
perfEvent,
error,
perfEvent.category === "error" ? LogLevel.error : logLevel,
perfEvent.category === "error" ? LogLevel.essential : (logLevel ?? LogLevel.essential),
);
}

Expand Down Expand Up @@ -518,8 +518,8 @@ export class ChildLogger extends TelemetryLogger {
}

private shouldFilterOutEvent(event: ITelemetryBaseEvent, logLevel?: LogLevel): boolean {
const eventLogLevel = logLevel ?? LogLevel.default;
const configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.default;
const eventLogLevel = logLevel ?? LogLevel.essential;
const configLogLevel = this.baseLogger.minLogLevel ?? LogLevel.info;
// Filter out in case event log level is below what is wanted in config.
return eventLogLevel < configLogLevel;
}
Expand All @@ -533,7 +533,7 @@ export class ChildLogger extends TelemetryLogger {
if (this.shouldFilterOutEvent(event, logLevel)) {
return;
}
this.baseLogger.send(this.prepareEvent(event), logLevel);
this.baseLogger.send(this.prepareEvent(event), logLevel ?? LogLevel.essential);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happened to making logLevel required on send for the sub-classes? Now we have two places in the same flow filling in defaults

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It couldn't be made there might still be chances that ChildLogger and Multisink receive undefined from old containerRuntime (At least that's what I understood). @jason-ha to confirm

}
Comment thread
MarioJGMsoft marked this conversation as resolved.
}

Expand Down Expand Up @@ -618,7 +618,7 @@ export class MultiSinkLogger extends TelemetryLogger {

super(namespace, realProperties);
this.loggers = loggers;
this._minLogLevelOfAllLoggers = LogLevel.default;
this._minLogLevelOfAllLoggers = LogLevel.info;
this.calculateMinLogLevel();
}

Expand All @@ -630,7 +630,7 @@ export class MultiSinkLogger extends TelemetryLogger {
if (this.loggers.length > 0) {
const logLevels: LogLevel[] = [];
for (const logger of this.loggers) {
logLevels.push(logger.minLogLevel ?? LogLevel.default);
logLevels.push(logger.minLogLevel ?? LogLevel.info);
}
this._minLogLevelOfAllLoggers = Math.min(...logLevels) as LogLevel;
}
Expand All @@ -653,10 +653,10 @@ export class MultiSinkLogger extends TelemetryLogger {
*
* @param event - the event to send to all the registered logger
*/
public send(event: ITelemetryBaseEvent): void {
public send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {
const newEvent = this.prepareEvent(event);
for (const logger of this.loggers) {
logger.send(newEvent);
logger.send(newEvent, logLevel ?? LogLevel.essential);
}
}
}
Expand Down Expand Up @@ -693,14 +693,15 @@ export class PerformanceEvent {
* @param emitLogs - should this instance emit logs. If set to false, logs will not be emitted to the logger,
* but measurements will still be performed and any specified markers will be generated.
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
* @returns An instance of {@link PerformanceEvent}
Comment thread
MarioJGMsoft marked this conversation as resolved.
*/
public static start(
logger: TelemetryLoggerExt | ITelemetryLoggerExt,
event: ITelemetryGenericEventExt,
markers?: IPerformanceEventMarkers,
emitLogs: boolean = true,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
): PerformanceEvent {
return new PerformanceEvent(
extractTelemetryLoggerExt(logger),
Expand All @@ -720,6 +721,7 @@ export class PerformanceEvent {
* @param sampleThreshold - events with the same name and category will be sent to the logger
* only when we hit this many executions of the task. If unspecified, all events will be sent.
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
* @returns The results of the executed task
Comment thread
MarioJGMsoft marked this conversation as resolved.
*
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
Expand All @@ -733,7 +735,7 @@ export class PerformanceEvent {
callback: (event: PerformanceEvent) => T,
markers?: IPerformanceEventMarkers,
sampleThreshold: number = 1,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
): T {
const perfEvent = PerformanceEvent.start(
logger,
Expand Down Expand Up @@ -762,6 +764,7 @@ export class PerformanceEvent {
* @param sampleThreshold - events with the same name and category will be sent to the logger
* only when we hit this many executions of the task. If unspecified, all events will be sent.
* @param logLevel - optional {@link LogLevel} for events emitted by this performance event.
* If unspecified, {@link @fluidframework/core-interfaces#LogLevelConst.essential | LogLevel.essential} will be used.
* @returns The results of the executed task
*
* @remarks Note that if the "same" event (category + eventName) would be emitted by different
Expand All @@ -775,7 +778,7 @@ export class PerformanceEvent {
callback: (event: PerformanceEvent) => Promise<T>,
markers?: IPerformanceEventMarkers,
sampleThreshold: number = 1,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
logLevel?: typeof LogLevel.verbose | typeof LogLevel.info,
): Promise<T> {
const perfEvent = PerformanceEvent.start(
logger,
Expand All @@ -802,12 +805,12 @@ export class PerformanceEvent {
private readonly startTime = performanceNow();
private startMark?: string;

protected constructor(
private constructor(
private readonly logger: TelemetryLoggerExt,
event: ITelemetryGenericEventExt,
private readonly markers: IPerformanceEventMarkers = { end: true, cancel: "generic" },
private readonly emitLogs: boolean = true,
private readonly logLevel?: typeof LogLevel.verbose | typeof LogLevel.default,
private readonly logLevel: typeof LogLevel.verbose | typeof LogLevel.info | undefined,
) {
this.event = { ...event };
if (this.markers.start) {
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/telemetry-utils/src/mockLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class MockLogger implements ITelemetryBaseLogger {
public readonly minLogLevel: LogLevel;

public constructor(minLogLevel?: LogLevel) {
this.minLogLevel = minLogLevel ?? LogLevel.default;
this.minLogLevel = minLogLevel ?? LogLevel.info;
}

/**
Expand All @@ -59,7 +59,7 @@ export class MockLogger implements ITelemetryBaseLogger {
* {@inheritDoc @fluidframework/core-interfaces#ITelemetryBaseLogger.send}
*/
public send(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {
if ((logLevel ?? LogLevel.default) >= this.minLogLevel) {
if ((logLevel ?? LogLevel.essential) >= this.minLogLevel) {
this._events.push(event);
}
}
Expand Down
Loading
Loading