mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
refactor: Update startActiveSpan method in Telemetry class
This commit is contained in:
parent
4563f42794
commit
fb8b00d383
@ -39,27 +39,28 @@ RunCron(
|
||||
timeoutInMS: OneUptimeDate.convertMinutesToMilliseconds(5),
|
||||
},
|
||||
async () => {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
return await Telemetry.startActiveSpan<Promise<void>>({
|
||||
name: "StatusPageCerts:OrderSSL",
|
||||
attributes: {
|
||||
jobName: "StatusPageCerts:OrderSSL",
|
||||
options: {
|
||||
attributes: {
|
||||
schedule: IsDevelopment ? EVERY_FIFTEEN_MINUTE : EVERY_FIFTEEN_MINUTE,
|
||||
runOnStartup: true,
|
||||
timeoutInMS: OneUptimeDate.convertMinutesToMilliseconds(5),
|
||||
},
|
||||
},
|
||||
fn: async (span: Span): Promise<void> => {
|
||||
try {
|
||||
await StatusPageDomainService.orderSSLForDomainsWhichAreNotOrderedYet();
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
await StatusPageDomainService.orderSSLForDomainsWhichAreNotOrderedYet();
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -27,57 +27,60 @@ const RunCron: RunCronFunction = (
|
||||
},
|
||||
runFunction: PromiseVoidFunction,
|
||||
): void => {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
return Telemetry.startActiveSpan<void>({
|
||||
name: "RunCron",
|
||||
attributes: {
|
||||
jobName: jobName,
|
||||
"options.schedule": options.schedule,
|
||||
"options.runOnStartup": options.runOnStartup,
|
||||
options: {
|
||||
attributes: {
|
||||
jobName: jobName,
|
||||
"options.schedule": options.schedule,
|
||||
"options.runOnStartup": options.runOnStartup,
|
||||
},
|
||||
},
|
||||
fn: (span: Span): void => {
|
||||
try {
|
||||
JobDictionary.setJobFunction(jobName, runFunction);
|
||||
|
||||
if (options.timeoutInMS) {
|
||||
JobDictionary.setTimeoutInMs(jobName, options.timeoutInMS);
|
||||
}
|
||||
|
||||
logger.debug("Adding job to the queue: " + jobName);
|
||||
|
||||
Queue.addJob(
|
||||
QueueName.Worker,
|
||||
jobName,
|
||||
jobName,
|
||||
{},
|
||||
{
|
||||
scheduleAt: options.schedule,
|
||||
},
|
||||
).catch((err: Error) => {
|
||||
return logger.error(err);
|
||||
});
|
||||
|
||||
if (options.runOnStartup) {
|
||||
Queue.addJob(QueueName.Worker, jobName, jobName, {}, {}).catch(
|
||||
(err: Error) => {
|
||||
return logger.error(err);
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
// log this error
|
||||
logger.error(err);
|
||||
|
||||
// record exception
|
||||
span.recordException(err as SpanException);
|
||||
|
||||
// set span status
|
||||
span.setStatus({
|
||||
code: SpanStatusCode.ERROR,
|
||||
});
|
||||
} finally {
|
||||
span.end();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
JobDictionary.setJobFunction(jobName, runFunction);
|
||||
|
||||
if (options.timeoutInMS) {
|
||||
JobDictionary.setTimeoutInMs(jobName, options.timeoutInMS);
|
||||
}
|
||||
|
||||
logger.debug("Adding job to the queue: " + jobName);
|
||||
|
||||
Queue.addJob(
|
||||
QueueName.Worker,
|
||||
jobName,
|
||||
jobName,
|
||||
{},
|
||||
{
|
||||
scheduleAt: options.schedule,
|
||||
},
|
||||
).catch((err: Error) => {
|
||||
return logger.error(err);
|
||||
});
|
||||
|
||||
if (options.runOnStartup) {
|
||||
Queue.addJob(QueueName.Worker, jobName, jobName, {}, {}).catch(
|
||||
(err: Error) => {
|
||||
return logger.error(err);
|
||||
},
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
// log this error
|
||||
logger.error(err);
|
||||
|
||||
// record exception
|
||||
span.recordException(err as SpanException);
|
||||
|
||||
// set span status
|
||||
span.setStatus({
|
||||
code: SpanStatusCode.ERROR,
|
||||
});
|
||||
} finally {
|
||||
span.end();
|
||||
}
|
||||
};
|
||||
|
||||
export default RunCron;
|
||||
|
@ -6,7 +6,7 @@ import Express, {
|
||||
} from "../Utils/Express";
|
||||
import logger from "../Utils/Logger";
|
||||
import Response from "../Utils/Response";
|
||||
import Telemetry, { Span, SpanStatusCode } from "../Utils/Telemetry";
|
||||
import Telemetry from "../Utils/Telemetry";
|
||||
import Exception from "Common/Types/Exception/Exception";
|
||||
import ServerException from "Common/Types/Exception/ServerException";
|
||||
|
||||
@ -92,13 +92,6 @@ export default class StatusAPI {
|
||||
router.get(
|
||||
"/status/live",
|
||||
async (req: ExpressRequest, res: ExpressResponse) => {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
name: "status.live",
|
||||
attributes: {
|
||||
status: "live",
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
logger.debug("Live check");
|
||||
await options.readyCheck();
|
||||
@ -109,15 +102,6 @@ export default class StatusAPI {
|
||||
status: "ok",
|
||||
});
|
||||
} catch (e) {
|
||||
// record exception
|
||||
span.recordException(e as Exception);
|
||||
|
||||
// set span status
|
||||
span.setStatus({
|
||||
code: SpanStatusCode.ERROR,
|
||||
message: "Live check failed",
|
||||
});
|
||||
|
||||
this.stausLiveFailed.add(1);
|
||||
Response.sendErrorResponse(
|
||||
req,
|
||||
@ -126,8 +110,6 @@ export default class StatusAPI {
|
||||
? e
|
||||
: new ServerException("Server is not ready"),
|
||||
);
|
||||
} finally {
|
||||
span.end();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -87,70 +87,73 @@ export class Service extends DatabaseService<StatusPageDomain> {
|
||||
}
|
||||
|
||||
public async orderCert(statusPageDomain: StatusPageDomain): Promise<void> {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
return Telemetry.startActiveSpan<Promise<void>>({
|
||||
name: "StatusPageDomainService.orderCert",
|
||||
attributes: {
|
||||
fullDomain: statusPageDomain.fullDomain,
|
||||
_id: statusPageDomain.id?.toString(),
|
||||
options: {
|
||||
attributes: {
|
||||
fullDomain: statusPageDomain.fullDomain,
|
||||
_id: statusPageDomain.id?.toString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
fn: async (span: Span): Promise<void> => {
|
||||
try {
|
||||
if (!statusPageDomain.fullDomain) {
|
||||
const fetchedStatusPageDomain: StatusPageDomain | null =
|
||||
await this.findOneBy({
|
||||
query: {
|
||||
_id: statusPageDomain.id!.toString(),
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
fullDomain: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
if (!statusPageDomain.fullDomain) {
|
||||
const fetchedStatusPageDomain: StatusPageDomain | null =
|
||||
await this.findOneBy({
|
||||
query: {
|
||||
_id: statusPageDomain.id!.toString(),
|
||||
if (!fetchedStatusPageDomain) {
|
||||
throw new BadDataException("Domain not found");
|
||||
}
|
||||
|
||||
statusPageDomain = fetchedStatusPageDomain;
|
||||
}
|
||||
|
||||
if (!statusPageDomain.fullDomain) {
|
||||
throw new BadDataException(
|
||||
"Unable to order certificate because domain is null",
|
||||
);
|
||||
}
|
||||
|
||||
await GreenlockUtil.orderCert({
|
||||
domain: statusPageDomain.fullDomain as string,
|
||||
validateCname: async (fullDomain: string) => {
|
||||
return await this.isCnameValid(fullDomain);
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
fullDomain: true,
|
||||
});
|
||||
|
||||
// update the order.
|
||||
await this.updateOneById({
|
||||
id: statusPageDomain.id!,
|
||||
data: {
|
||||
isSslOrdered: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!fetchedStatusPageDomain) {
|
||||
throw new BadDataException("Domain not found");
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
statusPageDomain = fetchedStatusPageDomain;
|
||||
}
|
||||
|
||||
if (!statusPageDomain.fullDomain) {
|
||||
throw new BadDataException(
|
||||
"Unable to order certificate because domain is null",
|
||||
);
|
||||
}
|
||||
|
||||
await GreenlockUtil.orderCert({
|
||||
domain: statusPageDomain.fullDomain as string,
|
||||
validateCname: async (fullDomain: string) => {
|
||||
return await this.isCnameValid(fullDomain);
|
||||
},
|
||||
});
|
||||
|
||||
// update the order.
|
||||
await this.updateOneById({
|
||||
id: statusPageDomain.id!,
|
||||
data: {
|
||||
isSslOrdered: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async updateSslProvisioningStatusForAllDomains(): Promise<void> {
|
||||
@ -394,44 +397,45 @@ export class Service extends DatabaseService<StatusPageDomain> {
|
||||
}
|
||||
|
||||
public async orderSSLForDomainsWhichAreNotOrderedYet(): Promise<void> {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
return Telemetry.startActiveSpan<Promise<void>>({
|
||||
name: "StatusPageDomainService.orderSSLForDomainsWhichAreNotOrderedYet",
|
||||
attributes: {},
|
||||
});
|
||||
|
||||
try {
|
||||
const domains: Array<StatusPageDomain> = await this.findBy({
|
||||
query: {
|
||||
isSslOrdered: false,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
fullDomain: true,
|
||||
},
|
||||
limit: LIMIT_MAX,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const domain of domains) {
|
||||
options: { attributes: {} },
|
||||
fn: async (span: Span): Promise<void> => {
|
||||
try {
|
||||
await this.orderCert(domain);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
const domains: Array<StatusPageDomain> = await this.findBy({
|
||||
query: {
|
||||
isSslOrdered: false,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
fullDomain: true,
|
||||
},
|
||||
limit: LIMIT_MAX,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
for (const domain of domains) {
|
||||
try {
|
||||
await this.orderCert(domain);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public async verifyCnameWhoseCnameisNotVerified(): Promise<void> {
|
||||
|
@ -85,208 +85,217 @@ export default class GreenlockUtil {
|
||||
}
|
||||
|
||||
public static async removeDomain(domain: string): Promise<void> {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
name: "GreenlockUtil.removeDomain",
|
||||
attributes: {
|
||||
domain: domain,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
// remove certificate for this domain.
|
||||
await AcmeCertificateService.deleteBy({
|
||||
query: {
|
||||
return await Telemetry.startActiveSpan<Promise<void>>({
|
||||
name: "GreenlockUtil.orderCert",
|
||||
options: {
|
||||
attributes: {
|
||||
domain: domain,
|
||||
},
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
fn: async (span: Span): Promise<void> => {
|
||||
try {
|
||||
// remove certificate for this domain.
|
||||
await AcmeCertificateService.deleteBy({
|
||||
query: {
|
||||
domain: domain,
|
||||
},
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
logger.error(`Error removing domain: ${domain}`);
|
||||
Telemetry.endSpan(span);
|
||||
} catch (err) {
|
||||
logger.error(`Error removing domain: ${domain}`);
|
||||
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: err,
|
||||
});
|
||||
|
||||
throw err;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public static async orderCert(data: {
|
||||
domain: string;
|
||||
validateCname: (domain: string) => Promise<boolean>;
|
||||
}): Promise<void> {
|
||||
const span: Span = Telemetry.startSpan({
|
||||
return await Telemetry.startActiveSpan<Promise<void>>({
|
||||
name: "GreenlockUtil.orderCert",
|
||||
attributes: {
|
||||
domain: data.domain,
|
||||
options: {
|
||||
attributes: {
|
||||
domain: data.domain,
|
||||
},
|
||||
},
|
||||
});
|
||||
fn: async (span: Span): Promise<void> => {
|
||||
try {
|
||||
let { domain } = data;
|
||||
|
||||
try {
|
||||
let { domain } = data;
|
||||
domain = domain.trim().toLowerCase();
|
||||
|
||||
domain = domain.trim().toLowerCase();
|
||||
const acmeAccountKeyInBase64: string = LetsEncryptAccountKey;
|
||||
|
||||
const acmeAccountKeyInBase64: string = LetsEncryptAccountKey;
|
||||
if (!acmeAccountKeyInBase64) {
|
||||
throw new ServerException(
|
||||
"No lets encrypt account key found in environment variables. Please add one.",
|
||||
);
|
||||
}
|
||||
|
||||
if (!acmeAccountKeyInBase64) {
|
||||
throw new ServerException(
|
||||
"No lets encrypt account key found in environment variables. Please add one.",
|
||||
);
|
||||
}
|
||||
let acmeAccountKey: string = Buffer.from(
|
||||
acmeAccountKeyInBase64,
|
||||
"base64",
|
||||
).toString();
|
||||
|
||||
let acmeAccountKey: string = Buffer.from(
|
||||
acmeAccountKeyInBase64,
|
||||
"base64",
|
||||
).toString();
|
||||
acmeAccountKey = Text.replaceAll(acmeAccountKey, "\\n", "\n");
|
||||
|
||||
acmeAccountKey = Text.replaceAll(acmeAccountKey, "\\n", "\n");
|
||||
//validate cname
|
||||
|
||||
//validate cname
|
||||
const isValidCname: boolean = await data.validateCname(domain);
|
||||
|
||||
const isValidCname: boolean = await data.validateCname(domain);
|
||||
if (!isValidCname) {
|
||||
await GreenlockUtil.removeDomain(domain);
|
||||
logger.error(`Cname is not valid for domain: ${domain}`);
|
||||
throw new BadDataException(
|
||||
"Cname is not valid for domain " + domain,
|
||||
);
|
||||
}
|
||||
|
||||
if (!isValidCname) {
|
||||
await GreenlockUtil.removeDomain(domain);
|
||||
logger.error(`Cname is not valid for domain: ${domain}`);
|
||||
throw new BadDataException("Cname is not valid for domain " + domain);
|
||||
}
|
||||
const client: acme.Client = new acme.Client({
|
||||
directoryUrl: acme.directory.letsencrypt.production,
|
||||
accountKey: acmeAccountKey,
|
||||
});
|
||||
|
||||
const client: acme.Client = new acme.Client({
|
||||
directoryUrl: acme.directory.letsencrypt.production,
|
||||
accountKey: acmeAccountKey,
|
||||
});
|
||||
const [certificateKey, certificateRequest] =
|
||||
await acme.crypto.createCsr({
|
||||
commonName: domain,
|
||||
});
|
||||
|
||||
const [certificateKey, certificateRequest] = await acme.crypto.createCsr({
|
||||
commonName: domain,
|
||||
});
|
||||
const certificate: string = await client.auto({
|
||||
csr: certificateRequest,
|
||||
email: LetsEncryptNotificationEmail.toString(),
|
||||
termsOfServiceAgreed: true,
|
||||
challengePriority: ["http-01"], // only http-01 challenge is supported by oneuptime
|
||||
challengeCreateFn: async (
|
||||
authz: acme.Authorization,
|
||||
challenge: Challenge,
|
||||
keyAuthorization: string,
|
||||
) => {
|
||||
// Satisfy challenge here
|
||||
/* http-01 */
|
||||
if (challenge.type === "http-01") {
|
||||
const acmeChallenge: AcmeChallenge = new AcmeChallenge();
|
||||
acmeChallenge.challenge = keyAuthorization;
|
||||
acmeChallenge.token = challenge.token;
|
||||
acmeChallenge.domain = authz.identifier.value;
|
||||
|
||||
const certificate: string = await client.auto({
|
||||
csr: certificateRequest,
|
||||
email: LetsEncryptNotificationEmail.toString(),
|
||||
termsOfServiceAgreed: true,
|
||||
challengePriority: ["http-01"], // only http-01 challenge is supported by oneuptime
|
||||
challengeCreateFn: async (
|
||||
authz: acme.Authorization,
|
||||
challenge: Challenge,
|
||||
keyAuthorization: string,
|
||||
) => {
|
||||
// Satisfy challenge here
|
||||
/* http-01 */
|
||||
if (challenge.type === "http-01") {
|
||||
const acmeChallenge: AcmeChallenge = new AcmeChallenge();
|
||||
acmeChallenge.challenge = keyAuthorization;
|
||||
acmeChallenge.token = challenge.token;
|
||||
acmeChallenge.domain = authz.identifier.value;
|
||||
await AcmeChallengeService.create({
|
||||
data: acmeChallenge,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
challengeRemoveFn: async (
|
||||
authz: acme.Authorization,
|
||||
challenge: Challenge,
|
||||
) => {
|
||||
// Clean up challenge here
|
||||
|
||||
await AcmeChallengeService.create({
|
||||
data: acmeChallenge,
|
||||
if (challenge.type === "http-01") {
|
||||
await AcmeChallengeService.deleteBy({
|
||||
query: {
|
||||
domain: authz.identifier.value,
|
||||
},
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// get expires at date from certificate
|
||||
const cert: acme.CertificateInfo =
|
||||
acme.crypto.readCertificateInfo(certificate);
|
||||
const issuedAt: Date = cert.notBefore;
|
||||
const expiresAt: Date = cert.notAfter;
|
||||
|
||||
// check if the certificate is already in the database.
|
||||
const existingCertificate: AcmeCertificate | null =
|
||||
await AcmeCertificateService.findOneBy({
|
||||
query: {
|
||||
domain: domain,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
challengeRemoveFn: async (
|
||||
authz: acme.Authorization,
|
||||
challenge: Challenge,
|
||||
) => {
|
||||
// Clean up challenge here
|
||||
|
||||
if (challenge.type === "http-01") {
|
||||
await AcmeChallengeService.deleteBy({
|
||||
if (existingCertificate) {
|
||||
// update the certificate
|
||||
await AcmeCertificateService.updateBy({
|
||||
query: {
|
||||
domain: authz.identifier.value,
|
||||
domain: domain,
|
||||
},
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
data: {
|
||||
certificate: certificate.toString(),
|
||||
certificateKey: certificateKey.toString(),
|
||||
issuedAt: issuedAt,
|
||||
expiresAt: expiresAt,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// create the certificate
|
||||
const acmeCertificate: AcmeCertificate = new AcmeCertificate();
|
||||
|
||||
acmeCertificate.domain = domain;
|
||||
acmeCertificate.certificate = certificate.toString();
|
||||
acmeCertificate.certificateKey = certificateKey.toString();
|
||||
acmeCertificate.issuedAt = issuedAt;
|
||||
acmeCertificate.expiresAt = expiresAt;
|
||||
|
||||
await AcmeCertificateService.create({
|
||||
data: acmeCertificate,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// get expires at date from certificate
|
||||
const cert: acme.CertificateInfo =
|
||||
acme.crypto.readCertificateInfo(certificate);
|
||||
const issuedAt: Date = cert.notBefore;
|
||||
const expiresAt: Date = cert.notAfter;
|
||||
Telemetry.endSpan(span);
|
||||
} catch (e) {
|
||||
logger.error(`Error ordering certificate for domain: ${data.domain}`);
|
||||
|
||||
// check if the certificate is already in the database.
|
||||
const existingCertificate: AcmeCertificate | null =
|
||||
await AcmeCertificateService.findOneBy({
|
||||
query: {
|
||||
domain: domain,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: e,
|
||||
});
|
||||
|
||||
if (existingCertificate) {
|
||||
// update the certificate
|
||||
await AcmeCertificateService.updateBy({
|
||||
query: {
|
||||
domain: domain,
|
||||
},
|
||||
limit: 1,
|
||||
skip: 0,
|
||||
data: {
|
||||
certificate: certificate.toString(),
|
||||
certificateKey: certificateKey.toString(),
|
||||
issuedAt: issuedAt,
|
||||
expiresAt: expiresAt,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// create the certificate
|
||||
const acmeCertificate: AcmeCertificate = new AcmeCertificate();
|
||||
if (e instanceof Exception) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
acmeCertificate.domain = domain;
|
||||
acmeCertificate.certificate = certificate.toString();
|
||||
acmeCertificate.certificateKey = certificateKey.toString();
|
||||
acmeCertificate.issuedAt = issuedAt;
|
||||
acmeCertificate.expiresAt = expiresAt;
|
||||
|
||||
await AcmeCertificateService.create({
|
||||
data: acmeCertificate,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Telemetry.endSpan(span);
|
||||
} catch (e) {
|
||||
logger.error(`Error ordering certificate for domain: ${data.domain}`);
|
||||
|
||||
Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
|
||||
span,
|
||||
exception: e,
|
||||
});
|
||||
|
||||
if (e instanceof Exception) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
throw new ServerException(
|
||||
`Unable to order certificate for ${data.domain}. Please contact support at support@oneuptime.com for more information.`,
|
||||
);
|
||||
}
|
||||
throw new ServerException(
|
||||
`Unable to order certificate for ${data.domain}. Please contact support at support@oneuptime.com for more information.`,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import logger from "./Logger";
|
||||
export type Span = opentelemetry.api.Span;
|
||||
export type SpanStatus = opentelemetry.api.SpanStatus;
|
||||
export type SpanException = opentelemetry.api.Exception;
|
||||
export type SpanOptions = opentelemetry.api.SpanOptions;
|
||||
|
||||
export enum SpanStatusCode {
|
||||
UNSET = 0,
|
||||
@ -304,14 +305,14 @@ export default class Telemetry {
|
||||
return tracer;
|
||||
}
|
||||
|
||||
public static startSpan(data: {
|
||||
public static startActiveSpan<T>(data: {
|
||||
name: string;
|
||||
attributes?: opentelemetry.api.Attributes;
|
||||
}): Span {
|
||||
const { name, attributes } = data;
|
||||
options?: SpanOptions | undefined;
|
||||
fn: (span: Span) => T;
|
||||
}): T {
|
||||
const { name } = data;
|
||||
|
||||
const span: Span = this.getTracer().startSpan(name, attributes);
|
||||
return span;
|
||||
return this.getTracer().startActiveSpan(name, data.options || {}, data.fn);
|
||||
}
|
||||
|
||||
public static recordExceptionMarkSpanAsErrorAndEndSpan(data: {
|
||||
|
Loading…
Reference in New Issue
Block a user