feat: improve sentry integration

This commit is contained in:
MiniDigger | Martin 2024-07-27 15:56:26 +02:00
parent 552a2035d4
commit ae7fe5495c
27 changed files with 1091 additions and 233 deletions

View File

@ -81,8 +81,10 @@ jobs:
run: |
if [[ $GITHUB_REF == 'refs/heads/master' ]]; then
echo "BACKEND_DATA_HOST=https://hangar.papermc.io" >> $GITHUB_ENV
echo "SENTRY_ENV=production" >> $GITHUB_ENV
else
echo "BACKEND_DATA_HOST=https://hangar.papermc.dev" >> $GITHUB_ENV
echo "SENTRY_ENV=staging" >> $GITHUB_ENV
fi
- name: Lint frontend

View File

@ -31,7 +31,7 @@
<spring-cloud-aws.version>3.1.1</spring-cloud-aws.version>
<!-- dependencies -->
<sentry.version>7.12.0</sentry.version>
<sentry.version>7.12.1</sentry.version>
<springdoc.version>2.6.0</springdoc.version>
<jsitemapgenerator.version>4.5</jsitemapgenerator.version>
<org-json.version>20240303</org-json.version>
@ -303,22 +303,6 @@
<version>${datafaker.version}</version>
</dependency>
<!-- tracing -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<!-- need this to fix an incompatibility with springboot 3.2/micrometer -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>${otel-semconv.version}</version>
</dependency>
<!--dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
</dependency-->
<!-- cache -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>

View File

@ -1,4 +1,4 @@
package io.papermc.hangar.observability;
package io.papermc.hangar.components.observability;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;

View File

@ -0,0 +1,13 @@
package io.papermc.hangar.components.observability;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.Cache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
public class SentryCacheManager extends CaffeineCacheManager {
@Override
public Cache getCache(@NotNull String name) {
return new SentryCacheWrapper(super.getCache(name));
}
}

View File

@ -0,0 +1,91 @@
package io.papermc.hangar.components.observability;
import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.util.StringUtils;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.Cache;
public class SentryCacheWrapper implements Cache {
private final Cache delegate;
public SentryCacheWrapper(Cache delegate) {
this.delegate = delegate;
}
@Override
public @NotNull String getName() {
return this.delegate.getName();
}
@Override
public @NotNull Object getNativeCache() {
return this.delegate.getNativeCache();
}
private <T> T trace(@NotNull Object key, String operation, Supplier<T> getter) {
final ISpan parentSpan = Sentry.getSpan();
if (parentSpan == null) {
return getter.get();
} else {
ISpan childSpan = parentSpan.startChild(operation, getName() + " " + key);
childSpan.setData("cache.name", getName());
childSpan.setData("cache.key", key instanceof Collection<?> ? key : List.of(key));
try {
var value = getter.get();
if (operation.equals("cache.get")) {
childSpan.setData("cache.hit", value != null);
}
// Set size of the cached value
childSpan.setData("cache.item_size", 123);
return value;
} finally {
childSpan.finish();
}
}
}
@Override
public ValueWrapper get(@NotNull Object key) {
return this.trace(key, "cache.get", () -> this.delegate.get(key));
}
@Override
public <T> T get(@NotNull Object key, Class<T> type) {
return this.trace(key, "cache.get", () -> this.delegate.get(key, type));
}
@Override
public <T> T get(@NotNull Object key, @NotNull Callable<T> valueLoader) {
return this.trace(key, "cache.get", () -> this.delegate.get(key, valueLoader));
}
@Override
public void put(@NotNull Object key, Object value) {
this.trace(key, "cache.put", () -> {
this.delegate.put(key, value);
return null;
});
}
@Override
public void evict(@NotNull Object key) {
this.trace(key, "cache.evict", () -> {
this.delegate.evict(key);
return null;
});
}
@Override
public void clear() {
this.delegate.clear();
}
}

View File

@ -1,8 +1,11 @@
package io.papermc.hangar.observability;
package io.papermc.hangar.components.observability;
import io.micrometer.common.lang.Nullable;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import io.sentry.ISpan;
import io.sentry.Sentry;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.CompletionStage;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -10,19 +13,9 @@ import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.annotation.Order;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.CompletionStage;
@Aspect
@Order(0)
public class CacheableObservationAspect {
private final ObservationRegistry registry;
public CacheableObservationAspect(final ObservationRegistry registry) {
this.registry = registry;
}
public class SentryCacheableAspect {
@Around("execution (@org.springframework.cache.annotation.Cacheable * *.*(..))")
@Nullable
@ -33,24 +26,27 @@ public class CacheableObservationAspect {
}
private Object observe(final ProceedingJoinPoint pjp, final Method method, final Cacheable cacheable) throws Throwable {
final Observation observation = Observation.createNotStarted(this.getName(cacheable, method), this.registry);
observation.lowCardinalityKeyValue("hangar.cache.key", Arrays.toString(pjp.getArgs()));
observation.highCardinalityKeyValue("hangar.cache.name", Arrays.toString(cacheable.value()));
observation.highCardinalityKeyValue("hangar.type", "CACHE");
if (CompletionStage.class.isAssignableFrom(method.getReturnType())) {
observation.start();
final Observation.Scope scope = observation.openScope();
try {
return ((CompletionStage<?>) pjp.proceed())
.whenComplete((result, error) -> this.stopObservation(observation, scope, error));
} catch (final Throwable error) {
this.stopObservation(observation, scope, error);
throw error;
} finally {
scope.close();
}
final ISpan parentSpan = Sentry.getSpan();
if (parentSpan == null) {
return pjp.proceed();
} else {
return observation.observeChecked(() -> pjp.proceed());
ISpan childSpan = parentSpan.startChild("cacheable", getName(cacheable, method));
childSpan.setData("cache.name",Arrays.toString(cacheable.value()));
childSpan.setData("cache.key", Arrays.toString(pjp.getArgs()));
if (CompletionStage.class.isAssignableFrom(method.getReturnType())) {
try {
return ((CompletionStage<?>) pjp.proceed())
.whenComplete((_, _) -> childSpan.finish());
} finally {
childSpan.finish();
}
} else {
try {
return pjp.proceed();
} finally {
childSpan.finish();
}
}
}
}
@ -59,11 +55,11 @@ public class CacheableObservationAspect {
if (cacheable.value().length == 0) {
name = "";
} else if (cacheable.value().length == 1) {
name = "(" + cacheable.value()[0] + ")";
name = cacheable.value()[0];
} else {
name = Arrays.toString(cacheable.value());
}
return "cacheable" + name + "-" + method.getDeclaringClass().getSimpleName() + "#" + method.getName();
return name + " " + method.getDeclaringClass().getSimpleName() + "#" + method.getName();
}
private Method getMethod(final ProceedingJoinPoint pjp) throws NoSuchMethodException {
@ -74,12 +70,4 @@ public class CacheableObservationAspect {
return method;
}
private void stopObservation(final Observation observation, final Observation.Scope scope, @Nullable final Throwable error) {
if (error != null) {
observation.error(error);
}
scope.close();
observation.stop();
}
}

View File

@ -0,0 +1,27 @@
package io.papermc.hangar.components.observability;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.spi.JdbiPlugin;
import org.jdbi.v3.core.statement.SqlLogger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class SentryConfig {
@Bean
public SentryCacheableAspect cacheableObservationAspect() {
return new SentryCacheableAspect();
}
@Bean
public JdbiPlugin observationPlugin() {
return new JdbiPlugin() {
@Override
public void customizeJdbi(final Jdbi jdbi) {
final SqlLogger myLogger = new SentrySqlLogger();
jdbi.setSqlLogger(myLogger);
}
};
}
}

View File

@ -0,0 +1,79 @@
package io.papermc.hangar.components.observability;
import io.sentry.ISpan;
import io.sentry.Sentry;
import io.sentry.SpanStatus;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.time.temporal.ChronoUnit;
import org.jdbi.v3.core.statement.SqlLogger;
import org.jdbi.v3.core.statement.StatementContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SentrySqlLogger implements SqlLogger {
private static final Logger sqlLog = LoggerFactory.getLogger("sql");
private final boolean logSql = false; // for debugging sql statements
@Override
public void logBeforeExecution(final StatementContext context) {
if (this.logSql) {
sqlLog.info("sql be: " + context.getRenderedSql());
}
ISpan parentSpan = Sentry.getSpan();
if (parentSpan == null) {
sqlLog.warn("No parent span for {}", this.getObservationName(context));
parentSpan = Sentry.startTransaction("unknown", "task");
}
ISpan childSpan = parentSpan.startChild("db.query", context.getRenderedSql());
childSpan.setData("db.system", "postgresql");
childSpan.setData("db.name", "hangar");
childSpan.setData("code.namespace", "Hangar");
childSpan.setData("code.lineno", "1");
childSpan.setData("code.filepath", context.getExtensionMethod().getMethod().getDeclaringClass().getSimpleName());
childSpan.setData("code.function", context.getExtensionMethod().getMethod().getName());
childSpan.setData("db.binding", context.getBinding().toString());
context.define("span", childSpan);
}
@Override
public void logAfterExecution(final StatementContext context) {
if (this.logSql) {
sqlLog.info("sql ae: " + context.getRenderedSql() + ", took " + context.getElapsedTime(ChronoUnit.MILLIS) + "ms");
}
final Object attr = context.getAttribute("span");
if (attr instanceof ISpan span) {
span.setStatus(SpanStatus.OK);
span.finish();
} else {
sqlLog.warn("No span for {}", this.getObservationName(context));
}
}
@Override
public void logException(final StatementContext context, final SQLException ex) {
if (this.logSql) {
sqlLog.info("sql e: " + context.getRenderedSql() + ", " + ex.getMessage());
}
final Object attr = context.getAttribute("span");
if (attr instanceof ISpan span) {
span.setThrowable(ex);
span.setStatus(SpanStatus.INTERNAL_ERROR);
span.finish();
} else {
sqlLog.warn("No span for {}", this.getObservationName(context));
}
}
private String getObservationName(final StatementContext context) {
if (context.getExtensionMethod() == null) {
return "unknown";
}
final Method method = context.getExtensionMethod().getMethod();
return method.getDeclaringClass().getSimpleName() + "#" + method.getName();
}
}

View File

@ -0,0 +1,24 @@
package io.papermc.hangar.components.observability;
import io.sentry.ITransaction;
import io.sentry.Sentry;
import io.sentry.SpanStatus;
import io.sentry.TransactionOptions;
public final class TransactionUtil {
public static void withTransaction(String op, String name, Runnable runnable) {
TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.setBindToScope(true);
ITransaction transaction = Sentry.startTransaction(name, op, transactionOptions);
try {
runnable.run();
} catch (Exception e) {
transaction.setThrowable(e);
transaction.setStatus(SpanStatus.INTERNAL_ERROR);
throw e;
} finally {
transaction.finish();
}
}
}

View File

@ -1,6 +1,7 @@
package io.papermc.hangar.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import io.papermc.hangar.components.observability.SentryCacheManager;
import io.papermc.hangar.service.ReplicationService;
import io.papermc.hangar.util.CacheWrapper;
import jakarta.annotation.PostConstruct;
@ -49,7 +50,7 @@ public class CacheConfig {
public CacheConfig(@Lazy final CacheMetricsRegistrar cacheMetricsRegistrar, final ReplicationService replicationService) {
this.cacheMetricsRegistrar = cacheMetricsRegistrar;
this.replicationService = replicationService;
this.cacheManager = new CaffeineCacheManager();
this.cacheManager = new SentryCacheManager();
}
@Bean(STAFF)
@ -203,7 +204,7 @@ public class CacheConfig {
.recordStats()
.build();
this.cacheManager.registerCustomCache(name, new CacheWrapper(name,caffineCache, this.replicationService));
this.cacheManager.registerCustomCache(name, new CacheWrapper<>(name,caffineCache, this.replicationService));
return this.cacheManager.getCache(name);
}
}

View File

@ -1,69 +0,0 @@
package io.papermc.hangar.config;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.aop.ObservedAspect;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.papermc.hangar.observability.CacheableObservationAspect;
import io.papermc.hangar.observability.ObservabilitySqlLogger;
import io.sentry.opentelemetry.OpenTelemetryLinkErrorEventProcessor;
import io.sentry.opentelemetry.SentryPropagator;
import io.sentry.opentelemetry.SentrySpanProcessor;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.spi.JdbiPlugin;
import org.jdbi.v3.core.statement.SqlLogger;
import org.springframework.boot.actuate.web.exchanges.InMemoryHttpExchangeRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@Configuration(proxyBeanMethods = false)
public class ObservabilityConfig {
private final ObservationRegistry observationRegistry;
public ObservabilityConfig(@Lazy final ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
@Bean
public InMemoryHttpExchangeRepository inMemoryHttpExchangeRepository() {
return new InMemoryHttpExchangeRepository();
}
@Bean
public ObservedAspect observedAspect() {
return new ObservedAspect(this.observationRegistry);
}
@Bean
public CacheableObservationAspect cacheableObservationAspect() {
return new CacheableObservationAspect(this.observationRegistry);
}
@Bean
public JdbiPlugin observationPlugin() {
return new JdbiPlugin() {
@Override
public void customizeJdbi(final Jdbi jdbi) {
final SqlLogger myLogger = new ObservabilitySqlLogger(ObservabilityConfig.this.observationRegistry);
jdbi.setSqlLogger(myLogger);
}
};
}
// sentry
@Bean
public SentrySpanProcessor sentrySpanProcessor() {
return new SentrySpanProcessor();
}
@Bean
public ContextPropagators sentryPropagators() {
return ContextPropagators.create(new SentryPropagator());
}
@Bean
public OpenTelemetryLinkErrorEventProcessor otelLinkEventProcessor() {
return new OpenTelemetryLinkErrorEventProcessor();
}
}

View File

@ -9,6 +9,7 @@ import io.netty.handler.timeout.WriteTimeoutHandler;
import io.papermc.hangar.config.hangar.HangarConfig;
import io.papermc.hangar.config.jackson.HangarAnnotationIntrospector;
import io.papermc.hangar.security.annotations.ratelimit.RateLimitInterceptor;
import io.sentry.spring.jakarta.SentryTaskDecorator;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
@ -204,8 +205,7 @@ public class WebConfig extends WebMvcConfigurationSupport {
}
@Bean
public RestClient restClient(final List<HttpMessageConverter<?>> messageConverters) {
final RestClient.Builder builder = RestClient.builder();
public RestClient restClient(final List<HttpMessageConverter<?>> messageConverters, RestClient.Builder builder) {
if (interceptorLogger.isDebugEnabled()) {
builder.requestInterceptor(new LoggingInterceptor());
}
@ -225,7 +225,9 @@ public class WebConfig extends WebMvcConfigurationSupport {
@Bean
protected ConcurrentTaskExecutor taskExecutor() {
return new ConcurrentTaskExecutor(Executors.newFixedThreadPool(10));
ConcurrentTaskExecutor taskExecutor = new ConcurrentTaskExecutor(Executors.newFixedThreadPool(10));
taskExecutor.setTaskDecorator(new SentryTaskDecorator());
return taskExecutor;
}
static class LoggingInterceptor implements ClientHttpRequestInterceptor {

View File

@ -1,76 +0,0 @@
package io.papermc.hangar.observability;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import org.jdbi.v3.core.statement.SqlLogger;
import org.jdbi.v3.core.statement.StatementContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.time.temporal.ChronoUnit;
import static io.micrometer.observation.Observation.createNotStarted;
public class ObservabilitySqlLogger implements SqlLogger {
private static final Logger sqlLog = LoggerFactory.getLogger("sql");
private final boolean logSql = false; // for debugging sql statements
private final ObservationRegistry observationRegistry;
public ObservabilitySqlLogger(final ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
@Override
public void logBeforeExecution(final StatementContext context) {
if (this.logSql) {
sqlLog.info("sql be: " + context.getRenderedSql());
}
final Observation observation = createNotStarted(this.getObservationName(context), this.observationRegistry);
observation.start();
observation.lowCardinalityKeyValue("hangar.sql.binding", context.getBinding().toString());
observation.highCardinalityKeyValue("hangar.sql.rendered", context.getRenderedSql());
observation.highCardinalityKeyValue("hangar.type", "SQL");
context.define("observation", observation);
}
@Override
public void logAfterExecution(final StatementContext context) {
if (this.logSql) {
sqlLog.info("sql ae: " + context.getRenderedSql() + ", took " + context.getElapsedTime(ChronoUnit.MILLIS) + "ms");
}
final Object attr = context.getAttribute("observation");
if (attr instanceof Observation observation) {
observation.stop();
} else {
sqlLog.warn("No observation for " + this.getObservationName(context));
}
}
@Override
public void logException(final StatementContext context, final SQLException ex) {
if (this.logSql) {
sqlLog.info("sql e: " + context.getRenderedSql() + ", " + ex.getMessage());
}
final Object attr = context.getAttribute("observation");
if (attr instanceof Observation observation) {
observation.error(ex);
observation.stop();
} else {
sqlLog.warn("No observation for " + this.getObservationName(context));
}
}
private String getObservationName(final StatementContext context) {
if (context.getExtensionMethod() == null) {
return "unknown";
}
final Method method = context.getExtensionMethod().getMethod();
return method.getDeclaringClass().getSimpleName().replace("DAO", "dao") + "#" + method.getName();
}
}

View File

@ -19,6 +19,8 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import static io.papermc.hangar.components.observability.TransactionUtil.withTransaction;
@Component
public class PopulationService {
@ -34,8 +36,10 @@ public class PopulationService {
@EventListener
public void populateTables(final ContextRefreshedEvent event) {
this.populateRoles();
this.populatePlatformVersions();
withTransaction("task", "PopulationService#populateTables()", () -> {
this.populateRoles();
this.populatePlatformVersions();
});
}
@SuppressWarnings("ResultOfMethodCallIgnored")

View File

@ -52,8 +52,8 @@ import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;

View File

@ -43,6 +43,8 @@ import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import static io.papermc.hangar.components.observability.TransactionUtil.withTransaction;
@Service
public class JarScanningService {
@ -73,18 +75,22 @@ public class JarScanningService {
@EventListener(ApplicationReadyEvent.class)
public void init() {
this.jarScannerUser = this.createUser();
EXECUTOR_SERVICE.execute(this::scanRemainingProjectVersions);
withTransaction("task", "JarScanningService#init", () -> {
this.jarScannerUser = this.createUser();
EXECUTOR_SERVICE.execute(this::scanRemainingProjectVersions);
});
}
@Transactional
public void scanRemainingProjectVersions() {
// TODO Pass this.scanner.version()
final List<VersionToScan> versionToScans = this.dao.versionsRequiringScans();
LOGGER.info("Rescanning " + versionToScans.size() + " versions");
for (final VersionToScan version : versionToScans) {
this.scan(version, false); // TODO partial parameter
}
withTransaction("task", "JarScanningService#scanRemainingProjectVersions", () -> {
// TODO Pass this.scanner.version()
final List<VersionToScan> versionToScans = this.dao.versionsRequiringScans();
LOGGER.info("Rescanning {} versions", versionToScans.size());
for (final VersionToScan version : versionToScans) {
this.scan(version, false); // TODO partial parameter
}
});
}
private UserTable createUser() {

View File

@ -2,6 +2,7 @@ package io.papermc.hangar.tasks;
import io.papermc.hangar.service.internal.admin.StatService;
import io.papermc.hangar.service.internal.projects.ProjectService;
import io.sentry.spring.jakarta.tracing.SentryTransaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -18,16 +19,19 @@ public class DbUpdateTask {
this.statService = statService;
}
@SentryTransaction(operation = "task", name = "DbUpdateTask#refreshHomePage")
@Scheduled(fixedRateString = "#{@hangarConfig.updateTasks.homepage.toMillis()}", initialDelay = 5_000)
public void refreshHomePage() {
this.projectService.refreshHomeProjects();
}
@SentryTransaction(operation = "task", name = "DbUpdateTask#updateVersionDownloads")
@Scheduled(fixedRateString = "#{@hangarConfig.updateTasks.versionDownloads.toMillis()}", initialDelay = 1000)
public void updateVersionDownloads() {
this.statService.processVersionDownloads();
}
@SentryTransaction(operation = "task", name = "DbUpdateTask#updateProjectViews")
@Scheduled(fixedRateString = "#{@hangarConfig.updateTasks.projectViews.toMillis()}", initialDelay = 1000)
public void updateProjectViews() {
this.statService.processProjectViews();

View File

@ -1,6 +1,7 @@
package io.papermc.hangar.tasks;
import io.papermc.hangar.service.internal.JobService;
import io.sentry.spring.jakarta.tracing.SentryTransaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -15,6 +16,7 @@ public class JobUpdateTask {
this.service = service;
}
@SentryTransaction(operation = "task", name = "JobUpdateTask#checkAndProcess")
@Scheduled(fixedRateString = "#{@hangarConfig.jobs.checkInterval.toMillis()}", initialDelayString = "#{@hangarConfig.jobs.checkInterval.toMillis()}")
public void checkAndProcess() {
this.service.checkAndProcess();

View File

@ -50,10 +50,6 @@ spring:
# use-fqn: true
management:
tracing:
enabled: false # set this to true if you have zipkin running locally
sampling:
probability: 1.0
endpoints:
enabled-by-default: true
web:

View File

@ -12,3 +12,4 @@ stringData:
HANGAR_ALLOW_INDEXING: "{{ .Values.base.allowIndexing }}"
DEBUG: "hangar:*"
NITRO_CLUSTER_WORKERS: "4"
SENTRY_ENV: "{{ .Values.backend.config.sentry.environment }}"

View File

@ -1,8 +0,0 @@
version: '3.7'
services:
zipkin:
image: openzipkin/zipkin
container_name: zipkin
ports:
- "9411:9411"

View File

@ -9,6 +9,8 @@ const backendHost = process.env.BACKEND_HOST || "http://localhost:8080";
const local = true; // set to false if backendData should be fetched from staging. You might need to hard reload (Ctrl+F5) the next page you're on when changing this value
const backendDataHost = process.env.BACKEND_DATA_HOST || (local ? "http://localhost:8080" : "https://hangar.papermc.dev");
const allowIndexing = process.env.HANGAR_ALLOW_INDEXING || "true";
const sentryDSN = process.env.SENTRY_DSN || "https://801c6e3ec217457e94b8d360e861242d@o4504989579804672.ingest.sentry.io/4504989584850944";
const sentryEnv = process.env.SENTRY_ENV || "local";
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
@ -40,6 +42,10 @@ export default defineNuxtConfig({
backendHost,
public: {
allowIndexing,
sentry: {
dsn: sentryDSN,
environment: sentryEnv,
},
},
},
modules: [

View File

@ -64,6 +64,9 @@
"@nuxt-alt/proxy": "2.5.8",
"@nuxtjs/eslint-config-typescript": "12.1.0",
"@nuxtjs/i18n": "8.3.1",
"@sentry/node": "8.20.0",
"@sentry/profiling-node": "8.20.0",
"@sentry/vue": "8.20.0",
"@types/accept-language-parser": "1.5.6",
"@types/debug": "4.1.12",
"@types/diff-match-patch": "1.0.36",

View File

@ -132,6 +132,15 @@ importers:
'@nuxtjs/i18n':
specifier: 8.3.1
version: 8.3.1(magicast@0.3.4)(rollup@4.19.0)(vue@3.4.33(typescript@5.5.3))
'@sentry/node':
specifier: 8.20.0
version: 8.20.0
'@sentry/profiling-node':
specifier: 8.20.0
version: 8.20.0
'@sentry/vue':
specifier: 8.20.0
version: 8.20.0(vue@3.4.33(typescript@5.5.3))
'@types/accept-language-parser':
specifier: 1.5.6
version: 1.5.6
@ -1105,6 +1114,160 @@ packages:
resolution: {integrity: sha512-VHnnjFTTep2oC5++61WY06y4c/h943NyHQh1CRUJQvjsdbGSMX3WQjMGk+X05a3pyPFN70aq0YbgtsEoEoTEjQ==}
engines: {node: ^14.16.0 || >=16.11.0}
'@opentelemetry/api-logs@0.52.1':
resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==}
engines: {node: '>=14'}
'@opentelemetry/api@1.9.0':
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
engines: {node: '>=8.0.0'}
'@opentelemetry/context-async-hooks@1.25.1':
resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/core@1.25.1':
resolution: {integrity: sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/instrumentation-connect@0.38.0':
resolution: {integrity: sha512-2/nRnx3pjYEmdPIaBwtgtSviTKHWnDZN3R+TkRUnhIVrvBKVcq+I5B2rtd6mr6Fe9cHlZ9Ojcuh7pkNh/xdWWg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-express@0.41.0':
resolution: {integrity: sha512-/B7fbMdaf3SYe5f1P973tkqd6s7XZirjpfkoJ63E7nltU30qmlgm9tY5XwZOzAFI0rHS9tbrFI2HFPAvQUFe/A==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-fastify@0.38.0':
resolution: {integrity: sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-graphql@0.42.0':
resolution: {integrity: sha512-N8SOwoKL9KQSX7z3gOaw5UaTeVQcfDO1c21csVHnmnmGUoqsXbArK2B8VuwPWcv6/BC/i3io+xTo7QGRZ/z28Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-hapi@0.40.0':
resolution: {integrity: sha512-8U/w7Ifumtd2bSN1OLaSwAAFhb9FyqWUki3lMMB0ds+1+HdSxYBe9aspEJEgvxAqOkrQnVniAPTEGf1pGM7SOw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-http@0.52.1':
resolution: {integrity: sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-ioredis@0.42.0':
resolution: {integrity: sha512-P11H168EKvBB9TUSasNDOGJCSkpT44XgoM6d3gRIWAa9ghLpYhl0uRkS8//MqPzcJVHr3h3RmfXIpiYLjyIZTw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-koa@0.42.0':
resolution: {integrity: sha512-H1BEmnMhho8o8HuNRq5zEI4+SIHDIglNB7BPKohZyWG4fWNuR7yM4GTlR01Syq21vODAS7z5omblScJD/eZdKw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-mongodb@0.46.0':
resolution: {integrity: sha512-VF/MicZ5UOBiXrqBslzwxhN7TVqzu1/LN/QDpkskqM0Zm0aZ4CVRbUygL8d7lrjLn15x5kGIe8VsSphMfPJzlA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-mongoose@0.40.0':
resolution: {integrity: sha512-niRi5ZUnkgzRhIGMOozTyoZIvJKNJyhijQI4nF4iFSb+FUx2v5fngfR+8XLmdQAO7xmsD8E5vEGdDVYVtKbZew==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-mysql2@0.40.0':
resolution: {integrity: sha512-0xfS1xcqUmY7WE1uWjlmI67Xg3QsSUlNT+AcXHeA4BDUPwZtWqF4ezIwLgpVZfHOnkAEheqGfNSWd1PIu3Wnfg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-mysql@0.40.0':
resolution: {integrity: sha512-d7ja8yizsOCNMYIJt5PH/fKZXjb/mS48zLROO4BzZTtDfhNCl2UM/9VIomP2qkGIFVouSJrGr/T00EzY7bPtKA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-nestjs-core@0.39.0':
resolution: {integrity: sha512-mewVhEXdikyvIZoMIUry8eb8l3HUjuQjSjVbmLVTt4NQi35tkpnHQrG9bTRBrl3403LoWZ2njMPJyg4l6HfKvA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-pg@0.43.0':
resolution: {integrity: sha512-og23KLyoxdnAeFs1UWqzSonuCkePUzCX30keSYigIzJe/6WSYA8rnEI5lobcxPEzg+GcU06J7jzokuEHbjVJNw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation-redis-4@0.41.0':
resolution: {integrity: sha512-H7IfGTqW2reLXqput4yzAe8YpDC0fmVNal95GHMLOrS89W+qWUKIqxolSh63hJyfmwPSFwXASzj7wpSk8Az+Dg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation@0.46.0':
resolution: {integrity: sha512-a9TijXZZbk0vI5TGLZl+0kxyFfrXHhX6Svtz7Pp2/VBlCSKrazuULEyoJQrOknJyFWNMEmbbJgOciHCCpQcisw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/instrumentation@0.52.1':
resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
'@opentelemetry/redis-common@0.36.2':
resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==}
engines: {node: '>=14'}
'@opentelemetry/resources@1.25.1':
resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/sdk-metrics@1.25.1':
resolution: {integrity: sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
'@opentelemetry/sdk-trace-base@1.25.1':
resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
'@opentelemetry/semantic-conventions@1.25.1':
resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==}
engines: {node: '>=14'}
'@opentelemetry/sql-common@0.40.1':
resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@parcel/watcher-android-arm64@2.4.1':
resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
engines: {node: '>= 10.0.0'}
@ -1200,6 +1363,9 @@ packages:
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
'@prisma/instrumentation@5.17.0':
resolution: {integrity: sha512-c1Sle4ji8aasMcYfBBHFM56We4ljfenVtRmS8aY06BllS7SoU6SmJBwG7vil+GHiR0Yrh+t9iBwt4AY0Jr4KNQ==}
'@refactorjs/http-proxy@0.2.14':
resolution: {integrity: sha512-JI35e5QjEWns3KPRw5j6cCiPN60GtOLR2bgr4hPr0kIgQaxVCVIEsWnalC0Avvy02a5a8NSmpjFbpoDESD1PxQ==}
engines: {node: '>=16.0.0'}
@ -1372,6 +1538,63 @@ packages:
cpu: [x64]
os: [win32]
'@sentry-internal/browser-utils@8.20.0':
resolution: {integrity: sha512-GGYNiELnT4ByidHyS4/M8UF8Oxagm5R13QyTncQGq8nZcQhcFZ9mdxLnf1/R4+j44Fph2Cgzafe8jGP/AMA9zw==}
engines: {node: '>=14.18'}
'@sentry-internal/feedback@8.20.0':
resolution: {integrity: sha512-mFvAoVpVShkDB2AgEr/dE96NSTPKI/lGMBznZMg7ZEcwZhLfH7HvLYCadIskRfzqFTLOUpbm9ciIO4SyR/4bDA==}
engines: {node: '>=14.18'}
'@sentry-internal/replay-canvas@8.20.0':
resolution: {integrity: sha512-LXV/pMH9KMw6CtImenMsiBkYIFIc97pDJ/rC7mVImKIROQ45fxGp/JBXM4Id0GENyA2+SySMWVQCAAapSfHZTw==}
engines: {node: '>=14.18'}
'@sentry-internal/replay@8.20.0':
resolution: {integrity: sha512-sCiI7SOAHq5XsxkixtoMofeSyKd/hVgDV+4145f6nN9m7nLzig4PBQwh2SgK2piJ2mfaXfqcdzA1pShPYldaJA==}
engines: {node: '>=14.18'}
'@sentry/browser@8.20.0':
resolution: {integrity: sha512-JDZbCreY44/fHYN28QzsAwEHXa2rc1hzM6GE4RSlXCdAhNfrjVxyYDxhw/50pVEHZg1WXxf7ZmERjocV5VJHsw==}
engines: {node: '>=14.18'}
'@sentry/core@8.20.0':
resolution: {integrity: sha512-R81snuw+67VT4aCxr6ShST/s0Y6FlwN2YczhDwaGyzumn5rlvA6A4JtQDeExduNoDDyv4T3LrmW8wlYZn3CJJw==}
engines: {node: '>=14.18'}
'@sentry/node@8.20.0':
resolution: {integrity: sha512-i4ywT2m0Gw65U3uwI4NwiNcyqp9YF6/RsusfH1pg4YkiL/RYp7FS0MPVgMggfvoue9S3KjCgRVlzTLwFATyPXQ==}
engines: {node: '>=14.18'}
'@sentry/opentelemetry@8.20.0':
resolution: {integrity: sha512-NFcLK6+t9wUc4HlGKeuDn6W4KjZxZfZmWlrK2/tgC5KzG1cnVeOnWUrJzGHTa+YDDdIijpjiFUcpXGPkX3rmIg==}
engines: {node: '>=14.18'}
peerDependencies:
'@opentelemetry/api': ^1.9.0
'@opentelemetry/core': ^1.25.1
'@opentelemetry/instrumentation': ^0.52.1
'@opentelemetry/sdk-trace-base': ^1.25.1
'@opentelemetry/semantic-conventions': ^1.25.1
'@sentry/profiling-node@8.20.0':
resolution: {integrity: sha512-vQaMYjPM7o0qvmj4atxXZywIDhnxMwTlc6x24eKqT8zN0OFBuIc1nYIacT7pEmd7R6e/mXdiG04GH1Vg0bHfOQ==}
engines: {node: '>=14.18'}
hasBin: true
'@sentry/types@8.20.0':
resolution: {integrity: sha512-6IP278KojOpiAA7vrd1hjhUyn26cl0n0nGsShzic5ztCVs92sTeVRnh7MTB9irDVtAbOEyt/YH6go3h+Jia1pA==}
engines: {node: '>=14.18'}
'@sentry/utils@8.20.0':
resolution: {integrity: sha512-+1I5H8dojURiEUGPliDwheQk8dhjp8uV1sMccR/W/zjFrt4wZyPs+Ttp/V7gzm9LDJoNek9tmELert/jQqWTgg==}
engines: {node: '>=14.18'}
'@sentry/vue@8.20.0':
resolution: {integrity: sha512-DFEJzvlx/eT7T6Ted9XYPAWZKNC9jPwUC+4b6oA69s44i/tYEFR9Oj0177YmAo69B7EpCIBQVntyS5Bbx0HtdQ==}
engines: {node: '>=14.18'}
peerDependencies:
vue: 2.x || 3.x
'@sindresorhus/is@4.6.0':
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
engines: {node: '>=10'}
@ -1482,6 +1705,9 @@ packages:
'@types/codemirror@5.60.15':
resolution: {integrity: sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==}
'@types/connect@3.4.36':
resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==}
'@types/cookie@0.6.0':
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
@ -1542,6 +1768,9 @@ packages:
'@types/ms@0.7.34':
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
'@types/mysql@2.15.22':
resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==}
'@types/node@20.14.11':
resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==}
@ -1551,6 +1780,12 @@ packages:
'@types/nprogress@0.2.3':
resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
'@types/pg-pool@2.0.4':
resolution: {integrity: sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==}
'@types/pg@8.6.1':
resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==}
'@types/prismjs@1.26.4':
resolution: {integrity: sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==}
@ -1566,6 +1801,9 @@ packages:
'@types/semver@7.5.8':
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
'@types/shimmer@1.2.0':
resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==}
'@types/swagger-schema-official@2.0.25':
resolution: {integrity: sha512-T92Xav+Gf/Ik1uPW581nA+JftmjWPgskw/WBf4TJzxRG/SJ+DfNnNE+WuZ4mrXuzflQMqMkm1LSYjzYW7MB1Cg==}
@ -2020,6 +2258,11 @@ packages:
accept-language-parser@1.5.0:
resolution: {integrity: sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==}
acorn-import-assertions@1.9.0:
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
peerDependencies:
acorn: ^8
acorn-import-attributes@1.9.5:
resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
peerDependencies:
@ -2321,6 +2564,9 @@ packages:
citty@0.1.6:
resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
cjs-module-lexer@1.3.1:
resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==}
classnames@2.5.1:
resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
@ -3447,6 +3693,12 @@ packages:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
import-in-the-middle@1.10.0:
resolution: {integrity: sha512-Z1jumVdF2GwnnYfM0a/y2ts7mZbwFMgt5rRuVmLgobgahC6iKgN5MBuXjzfTIOUpq5LSU10vJIPpVKe0X89fIw==}
import-in-the-middle@1.7.1:
resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==}
imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
@ -3986,6 +4238,9 @@ packages:
mlly@1.7.1:
resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
module-details-from-path@1.0.3:
resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==}
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
@ -4238,6 +4493,12 @@ packages:
resolution: {integrity: sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==}
hasBin: true
opentelemetry-instrumentation-fetch-node@1.2.3:
resolution: {integrity: sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==}
engines: {node: '>18.0.0'}
peerDependencies:
'@opentelemetry/api': ^1.6.0
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@ -4330,6 +4591,17 @@ packages:
perfect-debounce@1.0.0:
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
pg-int8@1.0.1:
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
engines: {node: '>=4.0.0'}
pg-protocol@1.6.1:
resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==}
pg-types@2.2.0:
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
engines: {node: '>=4'}
picocolors@1.0.1:
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
@ -4547,6 +4819,22 @@ packages:
resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
engines: {node: ^10 || ^12 || >=14}
postgres-array@2.0.0:
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
engines: {node: '>=4'}
postgres-bytea@1.0.0:
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
engines: {node: '>=0.10.0'}
postgres-date@1.0.7:
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
engines: {node: '>=0.10.0'}
postgres-interval@1.2.0:
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
engines: {node: '>=0.10.0'}
prebuild-install@7.1.2:
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
engines: {node: '>=10'}
@ -4706,6 +4994,10 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
require-in-the-middle@7.4.0:
resolution: {integrity: sha512-X34iHADNbNDfr6OTStIAHWSAvvKQRYgLO6duASaVf7J2VA3lvmNYboAHOuLC2huav1IwgZJtyEcJCKVzFxOSMQ==}
engines: {node: '>=8.6.0'}
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
@ -4861,6 +5153,9 @@ packages:
shell-quote@1.8.1:
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
shimmer@1.2.1:
resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==}
short-unique-id@5.2.0:
resolution: {integrity: sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==}
hasBin: true
@ -5824,6 +6119,10 @@ packages:
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -6859,6 +7158,210 @@ snapshots:
- vue
- vue-i18n-bridge
'@opentelemetry/api-logs@0.52.1':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api@1.9.0': {}
'@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/semantic-conventions': 1.25.1
'@opentelemetry/instrumentation-connect@0.38.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@types/connect': 3.4.36
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-express@0.41.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-fastify@0.38.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-graphql@0.42.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-hapi@0.40.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-http@0.52.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
semver: 7.6.3
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-ioredis@0.42.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/redis-common': 0.36.2
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-koa@0.42.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-mongodb@0.46.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-mongoose@0.40.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-mysql2@0.40.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0)
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-mysql@0.40.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@types/mysql': 2.15.22
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-nestjs-core@0.39.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-pg@0.43.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0)
'@types/pg': 8.6.1
'@types/pg-pool': 2.0.4
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation-redis-4@0.41.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/redis-common': 0.36.2
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/instrumentation@0.46.0(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@types/shimmer': 1.2.0
import-in-the-middle: 1.7.1
require-in-the-middle: 7.4.0
semver: 7.6.3
shimmer: 1.2.1
transitivePeerDependencies:
- supports-color
optional: true
'@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.52.1
'@types/shimmer': 1.2.0
import-in-the-middle: 1.10.0
require-in-the-middle: 7.4.0
semver: 7.6.3
shimmer: 1.2.1
transitivePeerDependencies:
- supports-color
'@opentelemetry/redis-common@0.36.2': {}
'@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
lodash.merge: 4.6.2
'@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@opentelemetry/semantic-conventions@1.25.1': {}
'@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@parcel/watcher-android-arm64@2.4.1':
optional: true
@ -6939,6 +7442,14 @@ snapshots:
'@popperjs/core@2.11.8': {}
'@prisma/instrumentation@5.17.0':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
transitivePeerDependencies:
- supports-color
'@refactorjs/http-proxy@0.2.14':
dependencies:
requires-port: 1.0.0
@ -7071,6 +7582,118 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.19.0':
optional: true
'@sentry-internal/browser-utils@8.20.0':
dependencies:
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry-internal/feedback@8.20.0':
dependencies:
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry-internal/replay-canvas@8.20.0':
dependencies:
'@sentry-internal/replay': 8.20.0
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry-internal/replay@8.20.0':
dependencies:
'@sentry-internal/browser-utils': 8.20.0
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry/browser@8.20.0':
dependencies:
'@sentry-internal/browser-utils': 8.20.0
'@sentry-internal/feedback': 8.20.0
'@sentry-internal/replay': 8.20.0
'@sentry-internal/replay-canvas': 8.20.0
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry/core@8.20.0':
dependencies:
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry/node@8.20.0':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-connect': 0.38.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-express': 0.41.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-fastify': 0.38.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-graphql': 0.42.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-hapi': 0.40.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-http': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-ioredis': 0.42.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-koa': 0.42.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-mongodb': 0.46.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-mongoose': 0.40.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-mysql': 0.40.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-mysql2': 0.40.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-nestjs-core': 0.39.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-pg': 0.43.0(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation-redis-4': 0.41.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@prisma/instrumentation': 5.17.0
'@sentry/core': 8.20.0
'@sentry/opentelemetry': 8.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
import-in-the-middle: 1.10.0
optionalDependencies:
opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0)
transitivePeerDependencies:
- supports-color
'@sentry/opentelemetry@8.20.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)':
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
'@sentry/profiling-node@8.20.0':
dependencies:
'@sentry/core': 8.20.0
'@sentry/node': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
detect-libc: 2.0.3
node-abi: 3.65.0
transitivePeerDependencies:
- supports-color
'@sentry/types@8.20.0': {}
'@sentry/utils@8.20.0':
dependencies:
'@sentry/types': 8.20.0
'@sentry/vue@8.20.0(vue@3.4.33(typescript@5.5.3))':
dependencies:
'@sentry/browser': 8.20.0
'@sentry/core': 8.20.0
'@sentry/types': 8.20.0
'@sentry/utils': 8.20.0
vue: 3.4.33(typescript@5.5.3)
'@sindresorhus/is@4.6.0': {}
'@sindresorhus/merge-streams@2.3.0': {}
@ -7422,6 +8045,10 @@ snapshots:
dependencies:
'@types/tern': 0.23.9
'@types/connect@3.4.36':
dependencies:
'@types/node': 20.14.11
'@types/cookie@0.6.0': {}
'@types/debug@4.1.12':
@ -7485,6 +8112,10 @@ snapshots:
'@types/ms@0.7.34': {}
'@types/mysql@2.15.22':
dependencies:
'@types/node': 20.14.11
'@types/node@20.14.11':
dependencies:
undici-types: 5.26.5
@ -7493,6 +8124,16 @@ snapshots:
'@types/nprogress@0.2.3': {}
'@types/pg-pool@2.0.4':
dependencies:
'@types/pg': 8.6.1
'@types/pg@8.6.1':
dependencies:
'@types/node': 20.14.11
pg-protocol: 1.6.1
pg-types: 2.2.0
'@types/prismjs@1.26.4': {}
'@types/qs@6.9.15': {}
@ -7505,6 +8146,8 @@ snapshots:
'@types/semver@7.5.8': {}
'@types/shimmer@1.2.0': {}
'@types/swagger-schema-official@2.0.25': {}
'@types/tern@0.23.9':
@ -8239,6 +8882,11 @@ snapshots:
accept-language-parser@1.5.0: {}
acorn-import-assertions@1.9.0(acorn@8.12.1):
dependencies:
acorn: 8.12.1
optional: true
acorn-import-attributes@1.9.5(acorn@8.12.1):
dependencies:
acorn: 8.12.1
@ -8581,6 +9229,8 @@ snapshots:
dependencies:
consola: 3.2.3
cjs-module-lexer@1.3.1: {}
classnames@2.5.1: {}
clean-regexp@1.0.0:
@ -9926,6 +10576,21 @@ snapshots:
parent-module: 1.0.1
resolve-from: 4.0.0
import-in-the-middle@1.10.0:
dependencies:
acorn: 8.12.1
acorn-import-attributes: 1.9.5(acorn@8.12.1)
cjs-module-lexer: 1.3.1
module-details-from-path: 1.0.3
import-in-the-middle@1.7.1:
dependencies:
acorn: 8.12.1
acorn-import-assertions: 1.9.0(acorn@8.12.1)
cjs-module-lexer: 1.3.1
module-details-from-path: 1.0.3
optional: true
imurmurhash@0.1.4: {}
indent-string@4.0.0: {}
@ -10453,6 +11118,8 @@ snapshots:
pkg-types: 1.1.3
ufo: 1.5.4
module-details-from-path@1.0.3: {}
mri@1.2.0: {}
mrmime@2.0.0: {}
@ -10577,7 +11244,6 @@ snapshots:
node-abi@3.65.0:
dependencies:
semver: 7.6.3
optional: true
node-abort-controller@3.1.1: {}
@ -10891,6 +11557,15 @@ snapshots:
undici: 5.28.4
yargs-parser: 21.1.1
opentelemetry-instrumentation-fetch-node@1.2.3(@opentelemetry/api@1.9.0):
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.25.1
transitivePeerDependencies:
- supports-color
optional: true
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@ -10975,6 +11650,18 @@ snapshots:
perfect-debounce@1.0.0: {}
pg-int8@1.0.1: {}
pg-protocol@1.6.1: {}
pg-types@2.2.0:
dependencies:
pg-int8: 1.0.1
postgres-array: 2.0.0
postgres-bytea: 1.0.0
postgres-date: 1.0.7
postgres-interval: 1.2.0
picocolors@1.0.1: {}
picomatch@2.3.1: {}
@ -11165,6 +11852,16 @@ snapshots:
picocolors: 1.0.1
source-map-js: 1.2.0
postgres-array@2.0.0: {}
postgres-bytea@1.0.0: {}
postgres-date@1.0.7: {}
postgres-interval@1.2.0:
dependencies:
xtend: 4.0.2
prebuild-install@7.1.2:
dependencies:
detect-libc: 2.0.3
@ -11338,6 +12035,14 @@ snapshots:
require-directory@2.1.1: {}
require-in-the-middle@7.4.0:
dependencies:
debug: 4.3.5
module-details-from-path: 1.0.3
resolve: 1.22.8
transitivePeerDependencies:
- supports-color
requires-port@1.0.0: {}
resolve-from@4.0.0: {}
@ -11520,6 +12225,8 @@ snapshots:
shell-quote@1.8.1: {}
shimmer@1.2.1: {}
short-unique-id@5.2.0: {}
should-equal@2.0.0:
@ -12618,6 +13325,8 @@ snapshots:
xmlchars@2.2.0: {}
xtend@4.0.2: {}
y18n@5.0.8: {}
yallist@3.1.1: {}

View File

@ -0,0 +1,25 @@
import * as Sentry from "@sentry/vue";
export default defineNuxtPlugin((nuxtApp) => {
const router = useRouter();
const {
public: { sentry },
} = useRuntimeConfig();
if (!sentry.dsn) {
return;
}
Sentry.init({
app: nuxtApp.vueApp,
dsn: sentry.dsn,
environment: sentry.environment,
integrations: [Sentry.browserTracingIntegration({ router }), Sentry.replayIntegration()],
tracePropagationTargets: ["http://localhost:3333", "https://hangar.papermc.dev", "https://hangar.papermc.io"],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
});

View File

@ -0,0 +1,41 @@
import * as Sentry from "@sentry/node";
import { nodeProfilingIntegration } from "@sentry/profiling-node";
import { H3Error } from "h3";
export default defineNitroPlugin((nitroApp) => {
const {
public: { sentry },
} = useRuntimeConfig();
if (!sentry.dsn) {
console.warn("Sentry DSN not set, skipping Sentry initialization");
return;
}
Sentry.init({
dsn: sentry.dsn,
environment: sentry.environment,
integrations: [nodeProfilingIntegration()],
tracesSampleRate: 1,
profilesSampleRate: 0.2,
});
nitroApp.hooks.hook("error", (error) => {
// Do not handle 404s and 422s
if (error instanceof H3Error) {
if (error.statusCode === 404 || error.statusCode === 422) {
return;
}
}
Sentry.captureException(error);
});
nitroApp.hooks.hook("request", (event) => {
event.context.$sentry = Sentry;
});
nitroApp.hooks.hookOnce("close", async () => {
await Sentry.close(2000);
});
});

View File

@ -0,0 +1,3 @@
{
"extends": "../../.nuxt/tsconfig.server.json"
}