chore: Move tracing decorators into the codebase (#4623)
* Vendorize tracing, finally fix service name issues * Upgrade datadaog-metrics, rename decorators -> tracing * lint
This commit is contained in:
@@ -68,7 +68,6 @@
|
||||
"@sentry/node": "^7.24.2",
|
||||
"@sentry/react": "^7.24.2",
|
||||
"@sentry/tracing": "^7.24.2",
|
||||
"@theo.gravity/datadog-apm": "^3.0.0",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@tommoor/remove-markdown": "^0.3.2",
|
||||
"@types/mermaid": "^9.1.0",
|
||||
@@ -86,8 +85,9 @@
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"core-js": "^3.26.1",
|
||||
"crypto-js": "^4.1.1",
|
||||
"datadog-metrics": "^0.9.3",
|
||||
"datadog-metrics": "^0.10.2",
|
||||
"date-fns": "^2.25.0",
|
||||
"dd-trace": "^3.9.3",
|
||||
"dotenv": "^4.0.0",
|
||||
"email-providers": "^1.13.1",
|
||||
"emoji-regex": "^10.0.0",
|
||||
|
||||
39
server/__mocks__/dd-trace.ts
Normal file
39
server/__mocks__/dd-trace.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
import { Tracer } from "dd-trace";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
const emptyFn = function () {};
|
||||
|
||||
const callableHandlers = {
|
||||
get<T, P extends keyof T>(_target: T, _prop: P, _receiver: any): T[P] {
|
||||
const newMock = new Proxy(emptyFn, callableHandlers);
|
||||
return (newMock as any) as T[P];
|
||||
},
|
||||
|
||||
apply<T extends (...args: any) => any, A extends Parameters<T>>(
|
||||
_target: T,
|
||||
_thisArg: any,
|
||||
_args: A
|
||||
): ReturnType<T> {
|
||||
const newMock = new Proxy(emptyFn, callableHandlers);
|
||||
return (newMock as any) as ReturnType<T>;
|
||||
},
|
||||
};
|
||||
|
||||
const callableMock = new Proxy(emptyFn, callableHandlers);
|
||||
|
||||
type MockTracer = Tracer & { isMock?: boolean };
|
||||
|
||||
export const mockTracer = new Proxy({} as MockTracer, {
|
||||
get<K extends keyof MockTracer>(_target: Tracer, key: K) {
|
||||
if (key === "isMock") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key === "wrap") {
|
||||
return (_: any, f: any) => f;
|
||||
}
|
||||
|
||||
return callableMock;
|
||||
},
|
||||
});
|
||||
@@ -1,11 +1,11 @@
|
||||
import { onAuthenticatePayload, Extension } from "@hocuspocus/server";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import Document from "@server/models/Document";
|
||||
import { can } from "@server/policies";
|
||||
import { getUserForJWT } from "@server/utils/jwt";
|
||||
import { AuthenticationError } from "../errors";
|
||||
|
||||
@APM.trace()
|
||||
@trace()
|
||||
export default class AuthenticationExtension implements Extension {
|
||||
async onAuthenticate({
|
||||
connection,
|
||||
|
||||
@@ -7,12 +7,12 @@ import {
|
||||
import * as Y from "yjs";
|
||||
import { sequelize } from "@server/database/sequelize";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import Document from "@server/models/Document";
|
||||
import documentCollaborativeUpdater from "../commands/documentCollaborativeUpdater";
|
||||
import markdownToYDoc from "./utils/markdownToYDoc";
|
||||
|
||||
@APM.trace()
|
||||
@trace()
|
||||
export default class PersistenceExtension implements Extension {
|
||||
/**
|
||||
* Map of documentId -> userIds that have modified the document since it
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
InvalidAuthenticationError,
|
||||
AuthenticationProviderDisabledError,
|
||||
} from "@server/errors";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { AuthenticationProvider, Collection, Team, User } from "@server/models";
|
||||
import teamProvisioner from "./teamProvisioner";
|
||||
import userProvisioner from "./userProvisioner";
|
||||
@@ -184,6 +184,6 @@ async function accountProvisioner({
|
||||
}
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "accountProvisioner",
|
||||
})(accountProvisioner);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
FileOperationType,
|
||||
FileOperationState,
|
||||
} from "@shared/types";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Collection, Event, Team, User, FileOperation } from "@server/models";
|
||||
import { getAWSKeyForFileOp } from "@server/utils/s3";
|
||||
|
||||
@@ -71,6 +71,6 @@ async function collectionExporter({
|
||||
return fileOperation;
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "collectionExporter",
|
||||
})(collectionExporter);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Transaction } from "sequelize";
|
||||
import utf8 from "utf8";
|
||||
import parseTitle from "@shared/utils/parseTitle";
|
||||
import { DocumentValidation } from "@shared/validations";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { User } from "@server/models";
|
||||
import dataURItoBuffer from "@server/utils/dataURItoBuffer";
|
||||
import parseImages from "@server/utils/parseImages";
|
||||
@@ -229,6 +229,6 @@ async function documentImporter({
|
||||
};
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "documentImporter",
|
||||
})(documentImporter);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import invariant from "invariant";
|
||||
import { Transaction } from "sequelize";
|
||||
import { ValidationError } from "@server/errors";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { User, Document, Collection, Pin, Event } from "@server/models";
|
||||
import pinDestroyer from "./pinDestroyer";
|
||||
|
||||
@@ -203,6 +203,6 @@ async function documentMover({
|
||||
return result;
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "documentMover",
|
||||
})(documentMover);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Transaction } from "sequelize";
|
||||
import slugify from "slugify";
|
||||
import { RESERVED_SUBDOMAINS } from "@shared/utils/domains";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Team, Event } from "@server/models";
|
||||
import { generateAvatarUrl } from "@server/utils/avatars";
|
||||
|
||||
@@ -103,6 +103,6 @@ async function findAvailableSubdomain(team: Team, requestedSubdomain: string) {
|
||||
return subdomain;
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "teamCreator",
|
||||
})(teamCreator);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Transaction } from "sequelize";
|
||||
import { sequelize } from "@server/database/sequelize";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import {
|
||||
ApiKey,
|
||||
Attachment,
|
||||
@@ -198,6 +198,6 @@ async function teamPermanentDeleter(team: Team) {
|
||||
}
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "teamPermanentDeleter",
|
||||
})(teamPermanentDeleter);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
InvalidAuthenticationError,
|
||||
MaximumTeamsError,
|
||||
} from "@server/errors";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Team, AuthenticationProvider } from "@server/models";
|
||||
|
||||
type TeamProvisionerResult = {
|
||||
@@ -125,6 +125,6 @@ async function teamProvisioner({
|
||||
};
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "teamProvisioner",
|
||||
})(teamProvisioner);
|
||||
|
||||
@@ -2,7 +2,7 @@ import nodemailer, { Transporter } from "nodemailer";
|
||||
import Oy from "oy-vey";
|
||||
import env from "@server/env";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import isCloudHosted from "@server/utils/isCloudHosted";
|
||||
import { baseStyles } from "./templates/components/EmailLayout";
|
||||
|
||||
@@ -22,7 +22,9 @@ type SendMailOptions = {
|
||||
/**
|
||||
* Mailer class to send emails.
|
||||
*/
|
||||
@APM.trace()
|
||||
@trace({
|
||||
serviceName: "mailer",
|
||||
})
|
||||
export class Mailer {
|
||||
transporter: Transporter | undefined;
|
||||
|
||||
|
||||
@@ -343,6 +343,11 @@ export class Environment {
|
||||
*/
|
||||
public DD_API_KEY = process.env.DD_API_KEY;
|
||||
|
||||
/**
|
||||
* The name of the service to use in DataDog.
|
||||
*/
|
||||
public DD_SERVICE = process.env.DD_SERVICE ?? "outline";
|
||||
|
||||
/**
|
||||
* Google OAuth2 client credentials. To enable authentication with Google.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable import/order */
|
||||
import env from "./env";
|
||||
|
||||
import "./logging/tracing"; // must come before importing any instrumented module
|
||||
import "./logging/tracer"; // must come before importing any instrumented module
|
||||
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
|
||||
@@ -5,7 +5,7 @@ import winston from "winston";
|
||||
import env from "@server/env";
|
||||
import Metrics from "@server/logging/Metrics";
|
||||
import Sentry from "@server/logging/sentry";
|
||||
import * as Tracing from "./tracing";
|
||||
import * as Tracing from "./tracer";
|
||||
|
||||
const isProduction = env.ENVIRONMENT === "production";
|
||||
|
||||
|
||||
@@ -29,13 +29,8 @@ class Metrics {
|
||||
return;
|
||||
}
|
||||
|
||||
const instanceId = process.env.INSTANCE_ID || process.env.HEROKU_DYNO_ID;
|
||||
|
||||
if (!instanceId) {
|
||||
throw new Error(
|
||||
"INSTANCE_ID or HEROKU_DYNO_ID must be set when using DataDog"
|
||||
);
|
||||
}
|
||||
const instanceId =
|
||||
process.env.INSTANCE_ID || process.env.HEROKU_DYNO_ID || process.pid;
|
||||
|
||||
return ddMetrics.gauge(key, value, [...tags, `instance:${instanceId}`]);
|
||||
}
|
||||
|
||||
92
server/logging/tracer.ts
Normal file
92
server/logging/tracer.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import tracer, { Span } from "dd-trace";
|
||||
import env from "@server/env";
|
||||
|
||||
type PrivateDatadogContext = {
|
||||
req: Record<string, any> & {
|
||||
_datadog?: {
|
||||
span?: Span;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// If the DataDog agent is installed and the DD_API_KEY environment variable is
|
||||
// in the environment then we can safely attempt to start the DD tracer
|
||||
if (env.DD_API_KEY) {
|
||||
tracer.init({
|
||||
version: env.VERSION,
|
||||
service: env.DD_SERVICE,
|
||||
env: env.ENVIRONMENT,
|
||||
});
|
||||
}
|
||||
|
||||
const getCurrentSpan = (): Span | null => tracer.scope().active();
|
||||
|
||||
/**
|
||||
* Add tags to a span to have more context about how and why it was running.
|
||||
* If added to the root span, tags are searchable and filterable.
|
||||
*
|
||||
* @param tags An object with the tags to add to the span
|
||||
* @param span An optional span object to add the tags to. If none provided,the current span will be used.
|
||||
*/
|
||||
export function addTags(tags: Record<string, any>, span?: Span | null): void {
|
||||
if (tracer) {
|
||||
const currentSpan = span || getCurrentSpan();
|
||||
|
||||
if (!currentSpan) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentSpan.addTags(tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The root span is an undocumented internal property that DataDog adds to `context.req`.
|
||||
* The root span is required in order to add searchable tags.
|
||||
* Unfortunately, there is no API to access the root span directly.
|
||||
* See: node_modules/dd-trace/src/plugins/util/web.js
|
||||
*
|
||||
* @param context A Koa context object
|
||||
*/
|
||||
export function getRootSpanFromRequestContext(
|
||||
context: PrivateDatadogContext
|
||||
): Span | null {
|
||||
// eslint-disable-next-line no-undef
|
||||
return context?.req?._datadog?.span ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the resource of the active APM span. This method wraps addTags to allow
|
||||
* safe use in environments where APM is disabled.
|
||||
*
|
||||
* @param name The name of the resource
|
||||
*/
|
||||
export function setResource(name: string) {
|
||||
if (tracer) {
|
||||
addTags({
|
||||
"resource.name": `${name}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the current active span as an error. This method wraps addTags to allow
|
||||
* safe use in environments where APM is disabled.
|
||||
*
|
||||
* @param error The error to add to the current span
|
||||
*/
|
||||
export function setError(error: Error, span?: Span) {
|
||||
if (tracer) {
|
||||
addTags(
|
||||
{
|
||||
errorMessage: error.message,
|
||||
"error.type": error.name,
|
||||
"error.msg": error.message,
|
||||
"error.stack": error.stack,
|
||||
},
|
||||
span
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default tracer;
|
||||
@@ -1,46 +1,212 @@
|
||||
import { init, tracer, addTags, markAsError } from "@theo.gravity/datadog-apm";
|
||||
// MIT License
|
||||
|
||||
// Copyright (c) 2020 GameChanger Media
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import { SpanOptions } from "dd-trace";
|
||||
import DDTags from "dd-trace/ext/tags";
|
||||
import env from "@server/env";
|
||||
import tracer, { setError } from "./tracer";
|
||||
|
||||
export * as APM from "@theo.gravity/datadog-apm";
|
||||
type DDTag = typeof DDTags[keyof typeof DDTags];
|
||||
|
||||
// If the DataDog agent is installed and the DD_API_KEY environment variable is
|
||||
// in the environment then we can safely attempt to start the DD tracer
|
||||
if (env.DD_API_KEY) {
|
||||
init(
|
||||
{
|
||||
version: env.VERSION,
|
||||
service: process.env.DD_SERVICE || "outline",
|
||||
},
|
||||
{
|
||||
useMock: env.ENVIRONMENT === "test",
|
||||
type Tags = {
|
||||
[tag in DDTag]?: any;
|
||||
} & {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
interface Constructor {
|
||||
new (...args: any[]): any;
|
||||
}
|
||||
|
||||
interface TraceConfig {
|
||||
className?: string;
|
||||
methodName?: string;
|
||||
serviceName?: string;
|
||||
spanName?: string;
|
||||
resourceName?: string;
|
||||
isRoot?: boolean;
|
||||
/** Cause the span to show up in trace search and analytics */
|
||||
makeSearchable?: boolean;
|
||||
tags?: Tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* This decorator will cause an individual function to be traced by the APM.
|
||||
*
|
||||
* @param config Optional configuration for the span that will be created for this trace.
|
||||
*/
|
||||
export const traceFunction = (config: TraceConfig) => <
|
||||
F extends (...args: any[]) => any,
|
||||
P extends Parameters<F>,
|
||||
R extends ReturnType<F>
|
||||
>(
|
||||
target: F
|
||||
): F =>
|
||||
env.ENVIRONMENT === "test"
|
||||
? target
|
||||
: (function wrapperFn(this: any, ...args: P): R {
|
||||
const {
|
||||
className,
|
||||
methodName = target.name,
|
||||
spanName = "DEFAULT_SPAN_NAME",
|
||||
makeSearchable: useAnalytics,
|
||||
tags,
|
||||
} = config;
|
||||
const childOf = config.isRoot
|
||||
? undefined
|
||||
: tracer.scope().active() || undefined;
|
||||
const resourceName = config.resourceName
|
||||
? config.resourceName
|
||||
: className
|
||||
? `${className}.${methodName}`
|
||||
: methodName;
|
||||
const spanOptions: SpanOptions = {
|
||||
childOf,
|
||||
tags: {
|
||||
[DDTags.RESOURCE_NAME]: resourceName,
|
||||
...tags,
|
||||
},
|
||||
};
|
||||
|
||||
const span = tracer.startSpan(spanName, spanOptions);
|
||||
|
||||
if (!span) {
|
||||
return target.call(this, ...args);
|
||||
}
|
||||
|
||||
if (config.serviceName) {
|
||||
span.setTag(
|
||||
DDTags.SERVICE_NAME,
|
||||
`${env.DD_SERVICE}-${config.serviceName}`
|
||||
);
|
||||
}
|
||||
|
||||
if (useAnalytics) {
|
||||
span.setTag(DDTags.ANALYTICS, true);
|
||||
}
|
||||
|
||||
// The callback fn needs to be wrapped in an arrow fn as the activate fn clobbers `this`
|
||||
return tracer.scope().activate(span, () => {
|
||||
const output = target.call(this, ...args);
|
||||
|
||||
if (output && typeof output.then === "function") {
|
||||
output
|
||||
.catch((error: Error) => {
|
||||
setError(error, span);
|
||||
})
|
||||
.finally(() => {
|
||||
span.finish();
|
||||
});
|
||||
} else {
|
||||
span.finish();
|
||||
}
|
||||
|
||||
return output;
|
||||
});
|
||||
} as F);
|
||||
|
||||
const traceMethod = (config?: TraceConfig) =>
|
||||
function <R, A extends any[], F extends (...args: A) => R>(
|
||||
target: any,
|
||||
_propertyKey: string,
|
||||
descriptor: PropertyDescriptor
|
||||
): TypedPropertyDescriptor<F> {
|
||||
const wrappedFn = descriptor.value;
|
||||
|
||||
if (wrappedFn) {
|
||||
const className = target.name || target.constructor.name; // target.name is needed if the target is the constructor itself
|
||||
const methodName = wrappedFn.name;
|
||||
descriptor.value = traceFunction({ ...config, className, methodName })(
|
||||
wrappedFn
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the resource of the active APM span. This method wraps addTags to allow
|
||||
* safe use in environments where APM is disabled.
|
||||
*
|
||||
* @param name The name of the resource
|
||||
*/
|
||||
export function setResource(name: string) {
|
||||
if (tracer) {
|
||||
addTags({
|
||||
"resource.name": `${name}`,
|
||||
return descriptor;
|
||||
};
|
||||
|
||||
const traceClass = (config?: TraceConfig) =>
|
||||
function <T extends Constructor>(constructor: T): void {
|
||||
const protoKeys = Reflect.ownKeys(constructor.prototype);
|
||||
protoKeys.forEach((key) => {
|
||||
if (key === "constructor") {
|
||||
return;
|
||||
}
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(
|
||||
constructor.prototype,
|
||||
key
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof key === "string" && typeof descriptor?.value === "function") {
|
||||
Object.defineProperty(
|
||||
constructor.prototype,
|
||||
key,
|
||||
traceMethod(config)(constructor, key, descriptor)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const staticKeys = Reflect.ownKeys(constructor);
|
||||
staticKeys.forEach((key) => {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(constructor, key);
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
if (typeof key === "string" && typeof descriptor?.value === "function") {
|
||||
Object.defineProperty(
|
||||
constructor,
|
||||
key,
|
||||
traceMethod(config)(constructor, key, descriptor)
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark the current active span as an error. This method wraps addTags to allow
|
||||
* safe use in environments where APM is disabled.
|
||||
* This decorator will cause the methods of a class, or an individual method, to be traced by the APM.
|
||||
*
|
||||
* @param error The error to add
|
||||
* @param config Optional configuration for the span that will be created for this trace.
|
||||
*/
|
||||
export function setError(error: Error) {
|
||||
if (tracer) {
|
||||
markAsError(error);
|
||||
// Going to rely on inferrence do its thing for this function
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export function trace(config?: TraceConfig) {
|
||||
function traceDecorator(target: Constructor): void;
|
||||
function traceDecorator<T>(
|
||||
target: Record<string, any>,
|
||||
propertyKey: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<T>
|
||||
): void;
|
||||
function traceDecorator(
|
||||
a: Constructor | Record<string, any>,
|
||||
b?: any,
|
||||
c?: any
|
||||
): void {
|
||||
if (typeof a === "function") {
|
||||
// Need to cast as there is no safe runtime way to check if a function is a constructor
|
||||
traceClass(config)(a as Constructor);
|
||||
} else {
|
||||
traceMethod(config)(a, b, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tracer;
|
||||
return traceDecorator;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Next } from "koa";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import tracer, { APM } from "@server/logging/tracing";
|
||||
import tracer, {
|
||||
addTags,
|
||||
getRootSpanFromRequestContext,
|
||||
} from "@server/logging/tracer";
|
||||
import { User, Team, ApiKey } from "@server/models";
|
||||
import { getUserForJWT } from "@server/utils/jwt";
|
||||
import {
|
||||
@@ -130,13 +133,13 @@ export default function auth(options: AuthenticationOptions = {}) {
|
||||
ctx.state.user = user;
|
||||
|
||||
if (tracer) {
|
||||
APM.addTags(
|
||||
addTags(
|
||||
{
|
||||
"request.userId": user.id,
|
||||
"request.teamId": user.teamId,
|
||||
"request.authType": ctx.state.authType,
|
||||
},
|
||||
APM.getRootSpanFromRequestContext(ctx)
|
||||
getRootSpanFromRequestContext(ctx)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { isRTL } from "@shared/utils/rtl";
|
||||
import unescape from "@shared/utils/unescape";
|
||||
import { parser, schema } from "@server/editor";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { trace } from "@server/logging/tracing";
|
||||
import type Document from "@server/models/Document";
|
||||
import type Revision from "@server/models/Revision";
|
||||
import User from "@server/models/User";
|
||||
@@ -43,7 +43,7 @@ type HTMLOptions = {
|
||||
signedUrls?: boolean;
|
||||
};
|
||||
|
||||
@APM.trace()
|
||||
@trace()
|
||||
export default class DocumentHelper {
|
||||
/**
|
||||
* Returns the document as a Prosemirror Node. This method uses the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Document } from "@server/models";
|
||||
import DocumentHelper from "@server/models/helpers/DocumentHelper";
|
||||
import presentUser from "./user";
|
||||
@@ -63,6 +63,6 @@ async function present(
|
||||
return data;
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "presentDocument",
|
||||
})(present);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { User } from "@server/models";
|
||||
|
||||
type Policy = {
|
||||
@@ -16,6 +16,6 @@ function present(user: User, objects: Record<string, any>[]): Policy[] {
|
||||
}));
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "presentPolicy",
|
||||
})(present);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Document, Collection, Team } from "@server/models";
|
||||
|
||||
type Action = {
|
||||
@@ -33,6 +33,6 @@ function present(
|
||||
};
|
||||
}
|
||||
|
||||
export default APM.traceFunction({
|
||||
export default traceFunction({
|
||||
spanName: "presentSlackAttachment",
|
||||
})(present);
|
||||
|
||||
@@ -6,8 +6,8 @@ import IO from "socket.io";
|
||||
import { createAdapter } from "socket.io-redis";
|
||||
import Logger from "@server/logging/Logger";
|
||||
import Metrics from "@server/logging/Metrics";
|
||||
import * as Tracing from "@server/logging/tracing";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import * as Tracing from "@server/logging/tracer";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import { Document, Collection, View, User } from "@server/models";
|
||||
import { can } from "@server/policies";
|
||||
import { getUserForJWT } from "@server/utils/jwt";
|
||||
@@ -131,7 +131,7 @@ export default function init(
|
||||
// Handle events from event queue that should be sent to the clients down ws
|
||||
const websockets = new WebsocketsProcessor();
|
||||
websocketQueue.process(
|
||||
APM.traceFunction({
|
||||
traceFunction({
|
||||
serviceName: "websockets",
|
||||
spanName: "process",
|
||||
isRoot: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Logger from "@server/logging/Logger";
|
||||
import * as Tracing from "@server/logging/tracing";
|
||||
import { APM } from "@server/logging/tracing";
|
||||
import { setResource } from "@server/logging/tracer";
|
||||
import { traceFunction } from "@server/logging/tracing";
|
||||
import {
|
||||
globalEventQueue,
|
||||
processorEventQueue,
|
||||
@@ -13,7 +13,7 @@ import tasks from "../queues/tasks";
|
||||
export default function init() {
|
||||
// This queue processes the global event bus
|
||||
globalEventQueue.process(
|
||||
APM.traceFunction({
|
||||
traceFunction({
|
||||
serviceName: "worker",
|
||||
spanName: "process",
|
||||
isRoot: true,
|
||||
@@ -21,7 +21,7 @@ export default function init() {
|
||||
const event = job.data;
|
||||
let err;
|
||||
|
||||
Tracing.setResource(`Event.${event.name}`);
|
||||
setResource(`Event.${event.name}`);
|
||||
|
||||
Logger.info("worker", `Processing ${event.name}`, {
|
||||
name: event.name,
|
||||
@@ -71,7 +71,7 @@ export default function init() {
|
||||
// Jobs for individual processors are processed here. Only applicable events
|
||||
// as unapplicable events were filtered in the global event queue above.
|
||||
processorEventQueue.process(
|
||||
APM.traceFunction({
|
||||
traceFunction({
|
||||
serviceName: "worker",
|
||||
spanName: "process",
|
||||
isRoot: true,
|
||||
@@ -79,7 +79,7 @@ export default function init() {
|
||||
const { event, name } = job.data;
|
||||
const ProcessorClass = processors[name];
|
||||
|
||||
Tracing.setResource(`Processor.${name}`);
|
||||
setResource(`Processor.${name}`);
|
||||
|
||||
if (!ProcessorClass) {
|
||||
throw new Error(
|
||||
@@ -107,7 +107,7 @@ export default function init() {
|
||||
|
||||
// Jobs for async tasks are processed here.
|
||||
taskQueue.process(
|
||||
APM.traceFunction({
|
||||
traceFunction({
|
||||
serviceName: "worker",
|
||||
spanName: "process",
|
||||
isRoot: true,
|
||||
@@ -115,7 +115,7 @@ export default function init() {
|
||||
const { name, props } = job.data;
|
||||
const TaskClass = tasks[name];
|
||||
|
||||
Tracing.setResource(`Task.${name}`);
|
||||
setResource(`Task.${name}`);
|
||||
|
||||
if (!TaskClass) {
|
||||
throw new Error(
|
||||
|
||||
215
yarn.lock
215
yarn.lock
@@ -1151,36 +1151,63 @@
|
||||
enabled "2.0.x"
|
||||
kuler "^2.0.0"
|
||||
|
||||
"@datadog/native-appsec@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-appsec/-/native-appsec-1.2.1.tgz#f9d4003b470608018c1f697e2d401202a3084632"
|
||||
integrity sha512-jF+k7xhBmJIYYLtjvhCey08RBbItTG7O2zcSCDGFffhvCvo3ZOoou+IKtAm9z+U7hOoeOmD+Xg+h29xj/BB9MA==
|
||||
"@datadog/datadog-api-client@^1.3.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/datadog-api-client/-/datadog-api-client-1.6.0.tgz#c09caa7e34ddaa346ba56c04c0e43bb288c501bd"
|
||||
integrity sha512-+iYaZt/yb7Unv4zIsh2WSdQU15cwsBTKrtpU4Z1wG90G2LFabqhWzARx/4qQ2Wms07hjUkA2rLTffd0+vGgyGA==
|
||||
dependencies:
|
||||
detect-libc "^1.0.3"
|
||||
minimist "^1.2.6"
|
||||
tar "^6.1.11"
|
||||
"@types/buffer-from" "^1.1.0"
|
||||
"@types/node" "*"
|
||||
"@types/pako" "^1.0.3"
|
||||
btoa "^1.2.1"
|
||||
buffer-from "^1.1.2"
|
||||
cross-fetch "^3.1.5"
|
||||
durations "^3.4.2"
|
||||
es6-promise "^4.2.4"
|
||||
form-data "^3.0.0"
|
||||
loglevel "^1.7.1"
|
||||
pako "^2.0.4"
|
||||
url-parse "^1.4.3"
|
||||
|
||||
"@datadog/native-metrics@^1.4.3":
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-metrics/-/native-metrics-1.4.3.tgz#30b62bdf227f3a193ca0ab06728a3ad9ccd70f1c"
|
||||
integrity sha512-EUOoTbCWEAqCp3Cswe3JR3DkK6GUaBQIz7sLPNdy1RDu6Zc39HNCXEDo5RL3Hexo87gDkOq+pRifLkxjwrf7gQ==
|
||||
"@datadog/native-appsec@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-appsec/-/native-appsec-2.0.0.tgz#ad65ba19bfd68e6b6c6cf64bb8ef55d099af8edc"
|
||||
integrity sha512-XHARZ6MVgbnfOUO6/F3ZoZ7poXHJCNYFlgcyS2Xetuk9ITA5bfcooX2B2F7tReVB+RLJ+j8bsm0t55SyF04KDw==
|
||||
dependencies:
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/pprof@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-1.0.2.tgz#835b2e8596738348a5ba81e5e399cdf3bc85bd35"
|
||||
integrity sha512-AMTK55W3Aa2QX2X8mN9SQfDGw3HvwIK9Or8pXQFss+kjtH5pCkO9oqE5838MeXgRh9BR8HWrjAQE3Ji7FRCK2g==
|
||||
"@datadog/native-iast-rewriter@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-rewriter/-/native-iast-rewriter-1.0.0.tgz#02bf338055cdcd3c5b3e8d528afe6d967985cf11"
|
||||
integrity sha512-DGN4cQd30mUaAB349gKeoDTt7acviBERnNYlyk8G+PlobuomTSEohJri5Jo4X+/5oRJPJngGX2VBq7YwMHiing==
|
||||
dependencies:
|
||||
node-gyp-build "^4.5.0"
|
||||
|
||||
"@datadog/native-iast-taint-tracking@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-1.0.0.tgz#d875cf0a3ef3907c27311386f85b3f3a9d99431b"
|
||||
integrity sha512-fS7XoRE5T4JQ7UzWjNT/wZQhS6nmLDwt12IDcSBZfRRJ2VyFth5GvOlQtCPa6Q0k7WMIrt9UXIl/v807cVq1SQ==
|
||||
dependencies:
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/native-metrics@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/native-metrics/-/native-metrics-1.5.0.tgz#e71b6b6d65f4bd58dfdffab2737890e8eef34584"
|
||||
integrity sha512-K63XMDx74RLhOpM8I9GGZR9ft0CNNB/RkjYPLHcVGvVnBR47zmWE2KFa7Yrtzjbk73+88PXI4nzqLyR3PJsaIQ==
|
||||
dependencies:
|
||||
node-gyp-build "^3.9.0"
|
||||
|
||||
"@datadog/pprof@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@datadog/pprof/-/pprof-1.1.1.tgz#17e86035140523ac3a96f3662e5dd29822042d61"
|
||||
integrity sha512-5lYXUpikQhrJwzODtJ7aFM0oKmPccISnTCecuWhjxIj4/7UJv0DamkLak634bgEW+kiChgkKFDapHSesuXRDXQ==
|
||||
dependencies:
|
||||
delay "^5.0.0"
|
||||
findit2 "^2.2.3"
|
||||
nan "^2.16.0"
|
||||
node-gyp-build "^3.9.0"
|
||||
p-limit "^3.1.0"
|
||||
pify "^5.0.0"
|
||||
protobufjs "^7.0.0"
|
||||
rimraf "^3.0.2"
|
||||
semver "^7.3.5"
|
||||
source-map "^0.7.3"
|
||||
split "^1.0.1"
|
||||
|
||||
@@ -2582,13 +2609,6 @@
|
||||
magic-string "^0.25.0"
|
||||
string.prototype.matchall "^4.0.6"
|
||||
|
||||
"@theo.gravity/datadog-apm@^3.0.0":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@theo.gravity/datadog-apm/-/datadog-apm-3.0.1.tgz#25a1e1aa40a72a121871a939e340208c9ad19138"
|
||||
integrity sha512-jzPKRWaVIjvbMaM1b7N5kQG8y9c7NrCkesAtlSpqhnXlyHjODOXVWdLi36H0NAr+xg9+oZ+Cja6NukJc2wGRWg==
|
||||
dependencies:
|
||||
dd-trace "^2.12.1"
|
||||
|
||||
"@tippyjs/react@^4.2.6":
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.2.6.tgz#971677a599bf663f20bb1c60a62b9555b749cc71"
|
||||
@@ -2674,6 +2694,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/body-scroll-lock/-/body-scroll-lock-3.1.0.tgz#435f6abf682bf58640e1c2ee5978320b891970e7"
|
||||
integrity sha512-3owAC4iJub5WPqRhxd8INarF2bWeQq1yQHBgYhN0XLBJMpd5ED10RrJ3aKiAwlTyL5wK7RkBD4SZUQz2AAAMdA==
|
||||
|
||||
"@types/buffer-from@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/buffer-from/-/buffer-from-1.1.0.tgz#fed6287e90fe524dc2b412e0fbc2222c1889c21f"
|
||||
integrity sha512-BLFpLBcN+RPKUsFxqRkMiwqTOOdi+TrKr5OpLJ9qCnUdSxS6S80+QRX/mIhfR66u0Ykc4QTkReaejOM2ILh+9Q==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/cheerio@*":
|
||||
version "0.22.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.30.tgz#6c1ded70d20d890337f0f5144be2c5e9ce0936e6"
|
||||
@@ -3105,7 +3132,7 @@
|
||||
"@types/node" "*"
|
||||
form-data "^3.0.0"
|
||||
|
||||
"@types/node@*", "@types/node@18.0.6", "@types/node@>=10.0.0", "@types/node@>=12", "@types/node@>=13.7.0":
|
||||
"@types/node@*", "@types/node@18.0.6", "@types/node@>=10.0.0", "@types/node@>=13.7.0":
|
||||
version "18.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7"
|
||||
integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==
|
||||
@@ -3129,6 +3156,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/orderedmap/-/orderedmap-1.0.0.tgz#807455a192bba52cbbb4517044bc82bdbfa8c596"
|
||||
integrity sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==
|
||||
|
||||
"@types/pako@^1.0.3":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pako/-/pako-1.0.4.tgz#b4262aef92680a9331fcdb8420c69cf3dd98d3f3"
|
||||
integrity sha512-Z+5bJSm28EXBSUJEgx29ioWeEEHUh6TiMkZHDhLwjc9wVFH+ressbkmX6waUZc5R3Gobn4Qu5llGxaoflZ+yhA==
|
||||
|
||||
"@types/parse-json@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
@@ -4632,11 +4664,6 @@ big.js@^5.2.2:
|
||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
||||
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
|
||||
|
||||
bignumber.js@^9.0.0:
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
|
||||
integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
|
||||
|
||||
binary-extensions@^1.0.0:
|
||||
version "1.13.1"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
|
||||
@@ -4846,6 +4873,11 @@ bser@2.1.1:
|
||||
dependencies:
|
||||
node-int64 "^0.4.0"
|
||||
|
||||
btoa@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
|
||||
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
@@ -4861,7 +4893,7 @@ buffer-equal@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
|
||||
integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
buffer-from@^1.0.0, buffer-from@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
@@ -5743,7 +5775,7 @@ cron-parser@^4.2.1:
|
||||
dependencies:
|
||||
luxon "^3.0.1"
|
||||
|
||||
cross-fetch@3.1.5, cross-fetch@^3.0.4:
|
||||
cross-fetch@3.1.5, cross-fetch@^3.0.4, cross-fetch@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
|
||||
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
|
||||
@@ -6208,29 +6240,30 @@ data-urls@^3.0.1, data-urls@^3.0.2:
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^11.0.0"
|
||||
|
||||
datadog-metrics@^0.9.3:
|
||||
version "0.9.3"
|
||||
resolved "https://registry.yarnpkg.com/datadog-metrics/-/datadog-metrics-0.9.3.tgz#e62d92b9619129805802d82111c8bcc4439fc859"
|
||||
integrity sha512-BVsBX2t+4yA3tHs7DnB5H01cHVNiGJ/bHA8y6JppJDyXG7s2DLm6JaozPGpgsgVGd42Is1CHRG/yMDQpt877Xg==
|
||||
datadog-metrics@^0.10.2:
|
||||
version "0.10.2"
|
||||
resolved "https://registry.yarnpkg.com/datadog-metrics/-/datadog-metrics-0.10.2.tgz#aece2c45874f0d8b7640ef93937f859517c535ed"
|
||||
integrity sha512-GP1zqzTJz0hjxbpD3LRutrKi9keGqnfq9O7z8tNgFaKGwuqSKH5cpwW7vvh6K8N43QJRFLyXACVmnv/aqEvylA==
|
||||
dependencies:
|
||||
debug "3.1.0"
|
||||
dogapi "2.8.4"
|
||||
"@datadog/datadog-api-client" "^1.3.0"
|
||||
debug "^4.1.0"
|
||||
|
||||
date-fns@^2.25.0, date-fns@^2.28.0, date-fns@^2.29.1:
|
||||
version "2.29.2"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.2.tgz#0d4b3d0f3dff0f920820a070920f0d9662c51931"
|
||||
integrity sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==
|
||||
|
||||
dd-trace@^2.12.1:
|
||||
version "2.18.0"
|
||||
resolved "https://registry.yarnpkg.com/dd-trace/-/dd-trace-2.18.0.tgz#04638b4aec21b5d62dcbd06c3beab52abd2cb84f"
|
||||
integrity sha512-1UVo3knRHA39/X5/qgBKjPmfjss7bSJcZAESk3g4FA9jmTh8NbozfWDbvk+nBXJI20Fcgc+Jamf0I9w5KAceRg==
|
||||
dd-trace@^3.9.3:
|
||||
version "3.9.3"
|
||||
resolved "https://registry.yarnpkg.com/dd-trace/-/dd-trace-3.9.3.tgz#99c44a30a172fb7f91f75e18ff7f7001df54854b"
|
||||
integrity sha512-30F9AoYozo9v3I6ycmDJl22XLbLapo2SmirAJh6ULjQ8q/Gb9yP1vf57bnFlTWjtdFgxxeBxVY/ksnTRzZcsew==
|
||||
dependencies:
|
||||
"@datadog/native-appsec" "^1.2.1"
|
||||
"@datadog/native-metrics" "^1.4.3"
|
||||
"@datadog/pprof" "^1.0.2"
|
||||
"@datadog/native-appsec" "2.0.0"
|
||||
"@datadog/native-iast-rewriter" "1.0.0"
|
||||
"@datadog/native-iast-taint-tracking" "1.0.0"
|
||||
"@datadog/native-metrics" "^1.5.0"
|
||||
"@datadog/pprof" "^1.1.1"
|
||||
"@datadog/sketches-js" "^2.1.0"
|
||||
"@types/node" ">=12"
|
||||
crypto-randomuuid "^1.0.0"
|
||||
diagnostics_channel "^1.1.0"
|
||||
ignore "^5.2.0"
|
||||
@@ -6248,6 +6281,7 @@ dd-trace@^2.12.1:
|
||||
module-details-from-path "^1.0.3"
|
||||
opentracing ">=0.12.1"
|
||||
path-to-regexp "^0.1.2"
|
||||
protobufjs "^7.1.2"
|
||||
retry "^0.10.1"
|
||||
semver "^5.5.0"
|
||||
|
||||
@@ -6256,13 +6290,6 @@ de-indent@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
|
||||
|
||||
debug@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
@@ -6309,11 +6336,6 @@ deep-equal@~1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
|
||||
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
|
||||
|
||||
deep-extend@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||
|
||||
deep-is@^0.1.3, deep-is@~0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
@@ -6424,11 +6446,6 @@ destroy@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||
|
||||
detect-libc@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||
integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
|
||||
|
||||
detect-newline@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
|
||||
@@ -6520,17 +6537,6 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dogapi@2.8.4:
|
||||
version "2.8.4"
|
||||
resolved "https://registry.yarnpkg.com/dogapi/-/dogapi-2.8.4.tgz#ada64f20c6acdea206b9fd9e70df0c96241b6621"
|
||||
integrity sha512-065fsvu5dB0o4+ENtLjZILvXMClDNH/yA9H6L8nsdcNiz9l0Hzpn7aQaCOPYXxqyzq4CRPOdwkFXUjDOXfRGbg==
|
||||
dependencies:
|
||||
extend "^3.0.2"
|
||||
json-bigint "^1.0.0"
|
||||
lodash "^4.17.21"
|
||||
minimist "^1.2.5"
|
||||
rc "^1.2.8"
|
||||
|
||||
dom-converter@^0.2:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
|
||||
@@ -6713,6 +6719,11 @@ duplexify@^3.4.2, duplexify@^3.6.0:
|
||||
readable-stream "^2.0.0"
|
||||
stream-shift "^1.0.0"
|
||||
|
||||
durations@^3.4.2:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/durations/-/durations-3.4.2.tgz#1de230454373cccfecab927de0bebae2295301db"
|
||||
integrity sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==
|
||||
|
||||
eastasianwidth@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
|
||||
@@ -7063,6 +7074,11 @@ es6-iterator@^2.0.3:
|
||||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-promise@^4.2.4:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||
|
||||
es6-symbol@^3.1.1, es6-symbol@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
|
||||
@@ -7511,7 +7527,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@^3.0.0, extend@^3.0.2:
|
||||
extend@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@@ -8829,7 +8845,7 @@ inherits@2.0.3:
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ini@^1.3.4, ini@~1.3.0:
|
||||
ini@^1.3.4:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
|
||||
integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
|
||||
@@ -9950,13 +9966,6 @@ jsesc@~0.5.0:
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
|
||||
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
|
||||
|
||||
json-bigint@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1"
|
||||
integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==
|
||||
dependencies:
|
||||
bignumber.js "^9.0.0"
|
||||
|
||||
json-loader@0.5.7:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
|
||||
@@ -10628,6 +10637,11 @@ logform@^2.2.0:
|
||||
ms "^2.1.1"
|
||||
triple-beam "^1.3.0"
|
||||
|
||||
loglevel@^1.7.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
|
||||
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
|
||||
|
||||
long@^5.0.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61"
|
||||
@@ -11171,7 +11185,7 @@ mz@^2.4.0:
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
nan@^2.12.1, nan@^2.16.0:
|
||||
nan@^2.12.1:
|
||||
version "2.17.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
|
||||
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
|
||||
@@ -11268,6 +11282,11 @@ node-gyp-build@^3.9.0:
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.9.0.tgz#53a350187dd4d5276750da21605d1cb681d09e25"
|
||||
integrity sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==
|
||||
|
||||
node-gyp-build@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
|
||||
integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
|
||||
|
||||
node-htmldiff@^0.9.4:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/node-htmldiff/-/node-htmldiff-0.9.4.tgz#d8fec52fbe736780afff28d2c8476ec106520887"
|
||||
@@ -11699,6 +11718,11 @@ pako@^1.0.5, pako@~1.0.2, pako@~1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
|
||||
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
|
||||
|
||||
pako@^2.0.4:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86"
|
||||
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
|
||||
|
||||
parallel-transform@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc"
|
||||
@@ -12449,7 +12473,7 @@ proto-list@~1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
|
||||
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
|
||||
|
||||
protobufjs@^7.0.0:
|
||||
protobufjs@^7.0.0, protobufjs@^7.1.2:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.1.2.tgz#a0cf6aeaf82f5625bffcf5a38b7cd2a7de05890c"
|
||||
integrity sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==
|
||||
@@ -12682,16 +12706,6 @@ raw-loader@^0.5.1:
|
||||
resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa"
|
||||
integrity sha1-DD0L6u2KAclm2Xh793goElKpeao=
|
||||
|
||||
rc@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||
dependencies:
|
||||
deep-extend "^0.6.0"
|
||||
ini "~1.3.0"
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-avatar-editor@^13.0.0:
|
||||
version "13.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-avatar-editor/-/react-avatar-editor-13.0.0.tgz#55013625ee9ae715c1fe2dc553b8079994d8a5f2"
|
||||
@@ -14342,11 +14356,6 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
|
||||
style-data@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/style-data/-/style-data-2.0.0.tgz#1cea7cf3b7658170b1addfbc7ee1036185318c06"
|
||||
@@ -14519,7 +14528,7 @@ tapable@^2.0.0, tapable@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
|
||||
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
|
||||
|
||||
tar@^6.0.2, tar@^6.1.11:
|
||||
tar@^6.0.2:
|
||||
version "6.1.11"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
|
||||
integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
|
||||
@@ -15164,7 +15173,7 @@ url-loader@^4.1.1:
|
||||
mime-types "^2.1.27"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
url-parse@^1.5.3:
|
||||
url-parse@^1.4.3, url-parse@^1.5.3:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
|
||||
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
|
||||
|
||||
Reference in New Issue
Block a user