Merged in feature/SW-3149-send-logs-to-sentry (pull request #2802)

Feature/SW-3149 send logs to sentry

* Use sentry for logging

* .

* fix(SW-3149) Send logs to Sentry

* remove experimental flag for logs

* add sentry settings for partner-sas

* feat(SW-3108): Added external link option to top primary button on content/collection page

Approved-by: Matilda Landström

* fix(BOOK-152): Removed old header references inside useStickyPosition hook to fix offset issue for the sitewide alert

Approved-by: Matilda Landström

* Merged in fix/LOY-360-team-member-text-for-retired-employees (pull request #2799)

fix(LOY-360): improve text for retired employees

* fix(LOY-360): improve text for retired employees


Approved-by: Erik Tiekstra
Approved-by: Matilda Landström

* Merged in fix/STAY-67-redirect-to-webview-after-gla (pull request #2795)

fix(STAY-67): redirect to webview after guarantee on my stay

* fix(STAY-67): redirect to webview after guarantee on my stay

* fix(STAY-67): add callback page for guarantee on webview


Approved-by: Linus Flood

* feat(SW-3152): Respecting image aspect ratio inside image gallery/lightbox

* feat(SW-3152): Respecting image aspect ratio inside image gallery/lightbox
* feat(BOOK-144): Make image clickable instead of a button to avoid being able to click outside of the image area

Approved-by: Bianca Widstam
Approved-by: Chuma Mcphoy (We Ahead)

* Merged in fix/BOOK-127-translate-validation-text (pull request #2800)

fix(BOOK-127): translate terms required message

* fix(BOOK-127): translate terms required message


Approved-by: Erik Tiekstra

* Merged in feat/LOY-354-L7-Progress-Card (pull request #2786)

Feat/LOY-354 L7 Progress Card

* feat(LOY-354): Add Trophy icon

* fix(LOY-354): include new tierPoints value

* feat(LOY-354): L7 Progress Level Card support

* refactor(LOY-354): Refactoring of component structure

* fix(LOY-354): Remove intl prop drilling

* fix(LOY-354): cleanup progress section code


Approved-by: Erik Tiekstra

* Merged in fix/BOOK-132-tracking-breakfast (pull request #2803)

fix(BOOK-132): add breakfastOption tracking

* fix(BOOK-132): add breakfastOption tracking


Approved-by: Joakim Jäderberg

* Merged in fix/enter-details-errors-missing (pull request #2806)

fix: Add missing messages to BookingFlowInput errors

* Add missing messages to BookingFlowInput errors

* Fix errors

* zippy zip

* phoney


Approved-by: Bianca Widstam
Approved-by: Joakim Jäderberg

* Merged in feature/copy-static-files-via-build-scripts (pull request #2798)

SW-3467 Copy static files via build scripts

* add file copy script and add all fonts to design-system

* add file copy script and add all fonts to design-system

* add file copy script and add all fonts to design-system

* remove fonts that will be copied via build scripts

* wip

* update paths to shared files

* update material-symbol script

* merge

* fix missing shared segment for path in fonts.css


Approved-by: Linus Flood

* Merged in feat/SW-2999-cleanup (pull request #2810)

feat(SW-2999): cleanup current web

* feat(SW-2999): cleanup current web

* Merge master

* Removed unused fonts


Approved-by: Joakim Jäderberg

* Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/SW-3149-send-logs-to-sentry

* Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/SW-3149-send-logs-to-sentry

* merge


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-09-18 07:59:44 +00:00
parent c09dc29fee
commit ae7a62c88f
20 changed files with 895 additions and 504 deletions

15
apps/partner-sas/env/client.ts vendored Normal file
View File

@@ -0,0 +1,15 @@
import { createEnv } from "@t3-oss/env-nextjs"
import { z } from "zod"
export const env = createEnv({
client: {
NEXT_PUBLIC_SENTRY_ENVIRONMENT: z.string().default("development"),
NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE: z.coerce.number().default(0.001),
},
emptyStringAsUndefined: true,
runtimeEnv: {
NEXT_PUBLIC_SENTRY_ENVIRONMENT: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE:
process.env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
},
})

View File

@@ -9,7 +9,6 @@ export const env = createEnv({
*/
isServer: typeof window === "undefined" || "Deno" in window,
server: {
PUBLIC_URL: z.string().default(""),
ADOBE_SDK_SCRIPT_SRC: z.string().optional(),
ENABLE_GTMSCRIPT: z
.string()
@@ -18,11 +17,16 @@ export const env = createEnv({
// transform to boolean
.transform((s) => s === "true")
.default("false"),
PUBLIC_URL: z.string().default(""),
SENTRY_ENVIRONMENT: z.string().default("development"),
SENTRY_SERVER_SAMPLERATE: z.coerce.number().default(0.001),
},
emptyStringAsUndefined: true,
runtimeEnv: {
PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
ADOBE_SDK_SCRIPT_SRC: process.env.ADOBE_SDK_SCRIPT_SRC,
ENABLE_GTMSCRIPT: process.env.ENABLE_GTMSCRIPT,
PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
SENTRY_ENVIRONMENT: process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
SENTRY_SERVER_SAMPLERATE: process.env.SENTRY_SERVER_SAMPLERATE,
},
})

View File

@@ -0,0 +1,25 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/client"
import { denyUrls } from "./instrumentation"
Sentry.init({
dsn: "https://130a3188ceac7bbf7b628ab511024956@o4508102497206272.ingest.de.sentry.io/4509587678167121",
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
enabled: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
sampleRate: env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
denyUrls: denyUrls,
// Disable logs for clients, will probably give us too much noise
enableLogs: false,
beforeSendLog(log) {
const ignoredLevels: (typeof log.level)[] = ["debug", "trace", "info"]
if (ignoredLevels.includes(log.level)) {
return null
}
return log
},
})
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart

View File

@@ -0,0 +1,25 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/server"
export const denyUrls: (string | RegExp)[] = [
// Ignore preview urls
/\/.{2}\/preview\//,
]
export async function register() {
await configureSentry()
}
export const onRequestError = Sentry.captureRequestError
async function configureSentry() {
Sentry.init({
dsn: "https://130a3188ceac7bbf7b628ab511024956@o4508102497206272.ingest.de.sentry.io/4509587678167121",
environment: env.SENTRY_ENVIRONMENT,
enabled: env.SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.SENTRY_SERVER_SAMPLERATE,
denyUrls: denyUrls,
enableLogs: true,
})
}

View File

@@ -62,6 +62,5 @@ export default Sentry.withSentryConfig(nextConfig, {
enabled: true,
},
hideSourceMaps: true,
disableLogger: true,
})

View File

@@ -24,7 +24,7 @@
"@scandic-hotels/design-system": "workspace:*",
"@scandic-hotels/tracking": "workspace:*",
"@scandic-hotels/trpc": "workspace:*",
"@sentry/nextjs": "^8.41.0",
"@sentry/nextjs": "^10.11.0",
"@swc/plugin-formatjs": "^3.2.2",
"@tanstack/react-query-devtools": "^5.75.5",
"next": "15.3.4",

View File

@@ -0,0 +1,25 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/client"
import { denyUrls } from "./instrumentation"
Sentry.init({
dsn: "https://fe39c070b4154e2f9cc35f0e5de0aedb@o4508102497206272.ingest.de.sentry.io/4508102500286544",
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
enabled: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
sampleRate: env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
denyUrls: denyUrls,
// Disable logs for clients, will probably give us too much noise
enableLogs: false,
beforeSendLog(log) {
const ignoredLevels: (typeof log.level)[] = ["debug", "trace", "info"]
if (ignoredLevels.includes(log.level)) {
return null
}
return log
},
})
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart

View File

@@ -1,6 +1,11 @@
import * as Sentry from "@sentry/nextjs"
import { isEdge } from "@scandic-hotels/common/utils/isEdge"
import { env } from "./env/server"
export const denyUrls: (string | RegExp)[] = [
// Ignore preview urls
/\/.{2}\/preview\//,
]
export async function register() {
await configureSentry()
@@ -9,9 +14,12 @@ export async function register() {
export const onRequestError = Sentry.captureRequestError
async function configureSentry() {
if (isEdge) {
await import("./sentry.edge.config")
} else {
await import("./sentry.server.config")
}
Sentry.init({
dsn: "https://fe39c070b4154e2f9cc35f0e5de0aedb@o4508102497206272.ingest.de.sentry.io/4508102500286544",
environment: env.SENTRY_ENVIRONMENT,
enabled: env.SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.SENTRY_SERVER_SAMPLERATE,
denyUrls: denyUrls,
enableLogs: true,
})
}

View File

@@ -467,6 +467,5 @@ export default Sentry.withSentryConfig(nextConfig, {
enabled: true,
},
hideSourceMaps: true,
disableLogger: true,
})

View File

@@ -44,7 +44,7 @@
"@scandic-hotels/design-system": "workspace:*",
"@scandic-hotels/tracking": "workspace:*",
"@scandic-hotels/trpc": "workspace:*",
"@sentry/nextjs": "^8.41.0",
"@sentry/nextjs": "^10.11.0",
"@swc/plugin-formatjs": "^3.2.2",
"@t3-oss/env-nextjs": "^0.13.4",
"@tanstack/react-query": "^5.75.5",

View File

@@ -1,19 +0,0 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/client"
import { denyUrls } from "./sentry.shared.config"
Sentry.init({
dsn: "https://fe39c070b4154e2f9cc35f0e5de0aedb@o4508102497206272.ingest.de.sentry.io/4508102500286544",
environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT,
enabled: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
// Set profilesSampleRate to 1.0 to profile every transaction.
// Since profilesSampleRate is relative to tracesSampleRate,
// the final profiling rate can be computed as tracesSampleRate * profilesSampleRate
// For example, a tracesSampleRate of 0.5 and profilesSampleRate of 0.5 would
// result in 25% of transactions being profiled (0.5*0.5=0.25)
profilesSampleRate: 0.01,
denyUrls: [...denyUrls],
})

View File

@@ -1,13 +0,0 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/server"
import { denyUrls } from "./sentry.shared.config"
Sentry.init({
dsn: "https://fe39c070b4154e2f9cc35f0e5de0aedb@o4508102497206272.ingest.de.sentry.io/4508102500286544",
environment: env.SENTRY_ENVIRONMENT,
enabled: env.SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.SENTRY_SERVER_SAMPLERATE,
denyUrls: [...denyUrls],
})

View File

@@ -1,12 +0,0 @@
import * as Sentry from "@sentry/nextjs"
import { env } from "./env/server"
import { denyUrls } from "./sentry.shared.config"
Sentry.init({
dsn: "https://fe39c070b4154e2f9cc35f0e5de0aedb@o4508102497206272.ingest.de.sentry.io/4508102500286544",
environment: env.SENTRY_ENVIRONMENT,
enabled: env.SENTRY_ENVIRONMENT !== "development",
tracesSampleRate: env.SENTRY_SERVER_SAMPLERATE,
denyUrls: [...denyUrls],
})

View File

@@ -1,4 +0,0 @@
export const denyUrls: (string | RegExp)[] = [
// Ignore preview urls
/\/.{2}\/preview\//,
]

View File

@@ -57,7 +57,6 @@
"@scandic-hotels/design-system": "workspace:*",
"@scandic-hotels/tracking": "workspace:*",
"@scandic-hotels/trpc": "workspace:*",
"@sentry/nextjs": "^8.41.0",
"@trpc/client": "^11.1.2",
"@vis.gl/react-google-maps": "^1.5.2",
"class-variance-authority": "^0.7.1",
@@ -82,6 +81,7 @@
"zustand": "^4.5.2"
},
"peerDependencies": {
"@sentry/nextjs": "^10",
"next": "^15",
"react": "^19"
},

View File

@@ -1,3 +1,28 @@
import * as Sentry from "@sentry/nextjs"
const logLevels = ["debug", "info", "warn", "error"] as const
const minimumLogLevel = (() => {
const configuredMinimumLogLevel = (
(process.env.MINIMUM_LOG_LEVEL ||
process.env.NEXT_PUBLIC_MINIMUM_LOG_LEVEL) ??
"info"
).toLowerCase() as (typeof logLevels)[number]
if (!logLevels.includes(configuredMinimumLogLevel)) {
console.warn(
`Invalid log level configured: ${configuredMinimumLogLevel}, defaulting to 'info'`
)
return "info"
}
return configuredMinimumLogLevel
})()
function shouldLog(level: (typeof logLevels)[number]) {
return logLevels.indexOf(level) >= logLevels.indexOf(minimumLogLevel)
}
export function createLogger(loggerPrefix: string | (() => Promise<string>)) {
const asyncWrapper: () => Promise<string> =
typeof loggerPrefix === "string" ? async () => loggerPrefix : loggerPrefix
@@ -11,39 +36,34 @@ export function createLogger(loggerPrefix: string | (() => Promise<string>)) {
return `[${prefix}]`
}
async function log(
level: (typeof logLevels)[number],
message: string,
...args: unknown[]
) {
if (!shouldLog(level)) {
return
}
Sentry.logger[level](`${await getLoggerPrefix()} ${message}`.trim(), {
...args,
})
console[level](`${await getLoggerPrefix()} ${message}`.trim(), ...args)
}
return {
async debug(message: string, ...args: unknown[]): Promise<void> {
// TODO: Make this configurable
if (process.env.NODE_ENV !== "development") {
return
}
console.debug(
"\x1b[36m%s\x1b[0m",
`${await getLoggerPrefix()} ${message}`.trim(),
...args
)
await log("debug", message, ...args)
},
async info(message: string, ...args: unknown[]): Promise<void> {
// TODO: Make this configurable
if (process.env.NODE_ENV !== "development") {
return
}
console.info(`${await getLoggerPrefix()} ${message}`.trim(), ...args)
await log("info", message, ...args)
},
async warn(message: string, ...args: unknown[]): Promise<void> {
console.warn(
`${await getLoggerPrefix()} [warn] - ${message}`.trim(),
...args
)
await log("warn", message, ...args)
},
async error(message: string, ...args: unknown[]): Promise<void> {
console.error(
`${await getLoggerPrefix()} [error] - ${message}`.trim(),
...args
)
await log("error", message, ...args)
},
}
}

View File

@@ -63,7 +63,7 @@
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@sentry/nextjs": "^8.41.0",
"@sentry/nextjs": "^10.11.0",
"@t3-oss/env-nextjs": "^0.13.4",
"deepmerge": "^4.3.1",
"flat": "^6.0.1",

View File

@@ -164,7 +164,7 @@ export function createCounter(meterName: string, counterName: string) {
const finalAttrs = sanitize(mergedAttrs)
counter.add(1, finalAttrs)
logger.info(`[${fullName}] start:`, finalAttrs)
logger.debug(`[${fullName}] start:`, finalAttrs)
},
/**
@@ -177,7 +177,7 @@ export function createCounter(meterName: string, counterName: string) {
const finalAttrs = sanitize(mergedAttrs)
success.add(1, finalAttrs)
logger.info(`[${fullName}] success:`, finalAttrs)
logger.debug(`[${fullName}] success:`, finalAttrs)
},
/**

View File

@@ -46,7 +46,6 @@
},
"dependencies": {
"@scandic-hotels/common": "workspace:*",
"@sentry/nextjs": "^8.41.0",
"@t3-oss/env-nextjs": "^0.13.4",
"@trpc/client": "^11.1.2",
"@trpc/react-query": "^11.1.2",
@@ -67,6 +66,7 @@
"zod": "^3.24.4"
},
"peerDependencies": {
"@sentry/nextjs": "^10",
"next": "^15",
"react": "^19"
},

1149
yarn.lock

File diff suppressed because it is too large Load Diff