Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loki: split tenants by organization rather than fleet #1902

Merged
merged 1 commit into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 21 additions & 14 deletions src/features/device-logs/lib/backends/loki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ function backoff<T extends (...args: any[]) => any>(
async function assertLokiLogContext(
ctx: LogContext & Partial<LokiLogContext>,
): Promise<LokiLogContext> {
if ('appId' in ctx) {
return ctx as types.RequiredField<typeof ctx, 'appId'>;
if ('appId' in ctx && 'orgId' in ctx) {
return ctx as types.RequiredField<typeof ctx, 'appId' | 'orgId'>;
}

const device = await sbvrUtils.api.resin.get({
Expand All @@ -110,22 +110,29 @@ async function assertLokiLogContext(
passthrough: { req: permissions.root },
options: {
$select: ['belongs_to__application'],
$expand: {
belongs_to__application: {
$select: ['id', 'organization'],
},
},
},
});

if (device == null) {
throw new Error(`Device '${ctx.id}' not found`);
}

// Mutate so that we don't have to repeatedly amend the same context and instead cache it
(ctx as Writable<typeof ctx>).appId =
`${device.belongs_to__application?.__id}`;

if (ctx.appId == null) {
if (device.belongs_to__application[0] == null) {
throw new Error(`Device '${ctx.id}' app not found`);
}

return ctx as types.RequiredField<typeof ctx, 'appId'>;
// Mutate so that we don't have to repeatedly amend the same context and instead cache it
(ctx as Writable<typeof ctx>).appId =
`${device.belongs_to__application[0].id}`;
(ctx as Writable<typeof ctx>).orgId =
`${device.belongs_to__application[0].organization.__id}`;

return ctx as types.RequiredField<typeof ctx, 'appId' | 'orgId'>;
}

export class LokiBackend implements DeviceLogsBackend {
Expand Down Expand Up @@ -189,7 +196,7 @@ export class LokiBackend implements DeviceLogsBackend {
const [, body] = await requestAsync({
url: `http://${lokiQueryAddress}/loki/api/v1/query_range`,
headers: {
'X-Scope-OrgID': ctx.appId,
'X-Scope-OrgID': ctx.orgId,
},
qs: {
query: this.getDeviceQuery(ctx),
Expand Down Expand Up @@ -262,7 +269,7 @@ export class LokiBackend implements DeviceLogsBackend {
await new Promise<loki.PushResponse>((resolve, reject) => {
this.pusher.push(
pushRequest,
loki.createOrgIdMetadata(ctx.appId),
loki.createOrgIdMetadata(ctx.orgId),
{
deadline: startAt + PUSH_TIMEOUT,
},
Expand Down Expand Up @@ -290,7 +297,7 @@ export class LokiBackend implements DeviceLogsBackend {

const call = this.querier.tail(
request,
loki.createOrgIdMetadata(ctx.appId),
loki.createOrgIdMetadata(ctx.orgId),
);
call.on('data', (response: loki.TailResponse) => {
const stream = response.getStream();
Expand Down Expand Up @@ -329,11 +336,11 @@ export class LokiBackend implements DeviceLogsBackend {
}

private getDeviceQuery(ctx: LokiLogContext) {
return `{application_id="${ctx.appId}"} | device_id="${ctx.id}"`;
return `{fleet_id="${ctx.appId}"} | device_id="${ctx.id}"`;
}

private getKey(ctx: LokiLogContext) {
return `a${ctx.appId}:d${ctx.id}`;
return `o${ctx.orgId}:a${ctx.appId}:d${ctx.id}`;
}

private getStructuredMetadata(ctx: LogContext): loki.LabelPairAdapter[] {
Expand All @@ -343,7 +350,7 @@ export class LokiBackend implements DeviceLogsBackend {
}

private getLabels(ctx: LokiLogContext): string {
return `{application_id="${ctx.appId}"}`;
return `{fleet_id="${ctx.appId}"}`;
}

private validateLog(log: DeviceLog): asserts log is DeviceLog {
Expand Down
1 change: 1 addition & 0 deletions src/features/device-logs/lib/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface LogContext {
readonly retention_limit: number;
}
export interface LokiLogContext extends LogContext {
readonly orgId: string;
readonly appId: string;
}

Expand Down
1 change: 1 addition & 0 deletions test/13_loki-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const createContext = (extra = {}): LokiLogContext => {
id: 1,
uuid: '1',
appId: '1',
orgId: '1',
retention_limit: 100,
...extra,
};
Expand Down
Loading