Skip to content

Commit

Permalink
refactor: move telemetry code to separate file to remove circular dep…
Browse files Browse the repository at this point in the history
…endency
  • Loading branch information
ewanharris committed Jun 26, 2024
1 parent 56197f3 commit daf0206
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 59 deletions.
5 changes: 2 additions & 3 deletions api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ import {
createRequestFunction,
RequestArgs,
CallResult,
PromiseResult,
attributeNames
} from "./common";
PromiseResult} from "./common";
import { attributeNames } from "./telemetry";
import { Configuration } from "./configuration";
import { Credentials } from "./credentials";
import { assertParamExists } from "./validation";
Expand Down
58 changes: 3 additions & 55 deletions common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@


import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import { Attributes, metrics } from "@opentelemetry/api";
import { SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_STATUS_CODE } from "@opentelemetry/semantic-conventions";
import { metrics } from "@opentelemetry/api";


import { Configuration } from "./configuration";
import { AuthCredentialsConfig, CredentialsMethod, type Credentials } from "./credentials";
import type { Credentials } from "./credentials";
import {
FgaApiError,
FgaApiInternalError,
Expand All @@ -28,6 +27,7 @@ import {
FgaError
} from "./errors";
import { setNotEnumerableProperty } from "./utils";
import { buildAttributes } from "./telemetry";

const meter = metrics.getMeter("@openfga/sdk", "0.5.0");
const durationHist = meter.createHistogram("fga-client.request.duration", {
Expand Down Expand Up @@ -231,55 +231,3 @@ export const createRequestFunction = function (axiosArgs: RequestArgs, axiosInst
};
};

/**
* Builds an object of attributes that can be used to report alongside an OpenTelemetry metric event.
*
* @param response - The Axios response object, used to add data like HTTP status, host, method, and headers.
* @param credentials - The credentials object, used to add data like the ClientID when using ClientCredentials.
* @param methodAttributes - Extra attributes that the method (i.e. check, listObjects) wishes to have included. Any custom attributes should use the common names.
* @returns {Attributes}
*/
export const buildAttributes = function buildAttributes(response: AxiosResponse<unknown, any>|undefined, credentials: AuthCredentialsConfig, methodAttributes: Record<string, any> = {}): Attributes {
const attributes: Attributes = {
...methodAttributes,
};

if (response?.status) {
attributes[SEMATTRS_HTTP_STATUS_CODE] = response.status;
}

if (response?.request) {
attributes[SEMATTRS_HTTP_METHOD] = response.request.method;
attributes[SEMATTRS_HTTP_HOST] = response.request.host;
}

if (response?.headers) {
const modelId = response.headers["openfga-authorization-model-id"];
if (modelId !== undefined) {
attributes[attributeNames.responseModelId] = modelId;
}
}

if (credentials?.method === CredentialsMethod.ClientCredentials) {
attributes[attributeNames.requestClientId] = credentials.config.clientId;
}

return attributes;
};

/**
* Common attribute names
*/
export const attributeNames = {
// Attributes associated with the request made
requestModelId: "fga-client.request.model_id",
requestMethod: "fga-client.request.method",
requestStoreId: "fga-client.request.store_id",
requestClientId: "fga-client.request.client_id",

// Attributes associated with the response
responseModelId: "fga-client.response.model_id",

// Attributes associated with specific actions
user: "fga-client.user"
};
3 changes: 2 additions & 1 deletion credentials/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import globalAxios, { AxiosInstance } from "axios";

import { assertParamExists, isWellFormedUriString } from "../validation";
import { FgaApiAuthenticationError, FgaApiError, FgaError, FgaValidationError } from "../errors";
import { attemptHttpRequest, buildAttributes } from "../common";
import { attemptHttpRequest } from "../common";
import { buildAttributes } from "../telemetry";
import { ApiTokenConfig, AuthCredentialsConfig, ClientCredentialsConfig, CredentialsMethod } from "./types";
import { Counter, metrics } from "@opentelemetry/api";

Expand Down
58 changes: 58 additions & 0 deletions telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { AxiosResponse } from "axios";
import { Attributes } from "@opentelemetry/api";
import { SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_STATUS_CODE } from "@opentelemetry/semantic-conventions";
import { AuthCredentialsConfig, CredentialsMethod } from "./credentials/types";

/**
* Builds an object of attributes that can be used to report alongside an OpenTelemetry metric event.
*
* @param response - The Axios response object, used to add data like HTTP status, host, method, and headers.
* @param credentials - The credentials object, used to add data like the ClientID when using ClientCredentials.
* @param methodAttributes - Extra attributes that the method (i.e. check, listObjects) wishes to have included. Any custom attributes should use the common names.
* @returns {Attributes}
*/

export const buildAttributes = function buildAttributes(response: AxiosResponse<unknown, any> | undefined, credentials: AuthCredentialsConfig, methodAttributes: Record<string, any> = {}): Attributes {
const attributes: Attributes = {
...methodAttributes,
};

if (response?.status) {
attributes[SEMATTRS_HTTP_STATUS_CODE] = response.status;
}

if (response?.request) {
attributes[SEMATTRS_HTTP_METHOD] = response.request.method;
attributes[SEMATTRS_HTTP_HOST] = response.request.host;
}

if (response?.headers) {
const modelId = response.headers["openfga-authorization-model-id"];
if (modelId !== undefined) {
attributes[attributeNames.responseModelId] = modelId;
}
}

if (credentials?.method === CredentialsMethod.ClientCredentials) {
attributes[attributeNames.requestClientId] = credentials.config.clientId;
}

return attributes;
};
/**
* Common attribute names
*/

export const attributeNames = {
// Attributes associated with the request made
requestModelId: "fga-client.request.model_id",
requestMethod: "fga-client.request.method",
requestStoreId: "fga-client.request.store_id",
requestClientId: "fga-client.request.client_id",

// Attributes associated with the response
responseModelId: "fga-client.response.model_id",

// Attributes associated with specific actions
user: "fga-client.user"
};

0 comments on commit daf0206

Please sign in to comment.