improve logging?

This commit is contained in:
Thomas Ruoff
2022-06-23 21:36:43 +02:00
committed by Thomas Ruoff
parent 942066bc7a
commit 00002a62d2
15 changed files with 91 additions and 50 deletions

View File

@@ -1,6 +1,7 @@
import React, { useEffect, useReducer } from 'react' import React, { useEffect, useReducer } from 'react'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { clearBookingData, loadBookingData } from '../helpers/storage' import { clearBookingData, loadBookingData } from '../helpers/storage'
import { log } from '../helpers/log'
import { createBooking } from '../helpers/booking' import { createBooking } from '../helpers/booking'
import { Booking } from '../db/booking' import { Booking } from '../db/booking'
@@ -156,7 +157,7 @@ export default function BookProvider({ children }) {
const booking = await createBooking(state.formData) const booking = await createBooking(state.formData)
router.push(`/bookings/${booking.uuid}/stored`) router.push(`/bookings/${booking.uuid}/stored`)
} catch (error) { } catch (error) {
console.error(error) log.error('Failed to store booking', error)
dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message }) dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message })
} }
} }

1
helpers/log.ts Normal file
View File

@@ -0,0 +1 @@
export { log } from 'next-axiom'

View File

@@ -1,5 +1,6 @@
import { Booking } from '../db/booking' import { Booking } from '../db/booking'
import { getBaseURL } from '../helpers/url' import { getBaseURL } from '../helpers/url'
import { log } from '../helpers/log'
import { daysFormatFrontend } from './date' import { daysFormatFrontend } from './date'
import { generateCalendarEntry } from './ical' import { generateCalendarEntry } from './ical'
import sgMail from '@sendgrid/mail' import sgMail from '@sendgrid/mail'
@@ -112,10 +113,7 @@ export async function sendReceivedBookingAdminMail(
textPlainContent: getReceivedBookingAdminText(booking), textPlainContent: getReceivedBookingAdminText(booking),
}) })
} catch (error) { } catch (error) {
console.error( log.error(`Failed in sendReceivedBookingMail for ${booking.uuid}`, error)
`Failed in sendReceivedBookingMail for ${booking.uuid}`,
error
)
} }
} }
@@ -130,10 +128,7 @@ export async function sendReceivedBookingBookerMail(
textPlainContent: getReceivedBookingBookerText(booking), textPlainContent: getReceivedBookingBookerText(booking),
}) })
} catch (error) { } catch (error) {
console.error( log.error(`Failed in sendReceivedBookingMail for ${booking.uuid}`, error)
`Failed in sendReceivedBookingMail for ${booking.uuid}`,
error
)
} }
} }
@@ -155,10 +150,7 @@ export async function sendBookingConfirmed(booking: Booking): Promise<void> {
], ],
}) })
} catch (error) { } catch (error) {
console.error( log.error(`Failed in sendBookingConfirmedMail for ${booking.uuid}`, error)
`Failed in sendBookingConfirmedMail for ${booking.uuid}`,
error
)
} }
} }
@@ -171,10 +163,7 @@ export async function sendBookingRejected(booking: Booking): Promise<void> {
textPlainContent: getBookingRejectedText(booking), textPlainContent: getBookingRejectedText(booking),
}) })
} catch (error) { } catch (error) {
console.error( log.error(`Failed in sendBookingRejectedMail for ${booking.uuid}`, error)
`Failed in sendBookingRejectedMail for ${booking.uuid}`,
error
)
} }
} }
@@ -187,10 +176,7 @@ export async function sendBookingCanceled(booking: Booking): Promise<void> {
textPlainContent: getBookingCanceledText(booking), textPlainContent: getBookingCanceledText(booking),
}) })
} catch (error) { } catch (error) {
console.error( log.error(`Failed in sendBookingCanceledMail for ${booking.uuid}`, error)
`Failed in sendBookingCanceledMail for ${booking.uuid}`,
error
)
} }
} }
@@ -222,10 +208,10 @@ async function sendMail({
try { try {
await sgMail.send(data) await sgMail.send(data)
} catch (error) { } catch (error) {
console.error(error) log.error(error)
if (error.response) { if (error.response) {
console.error(error.response.body) log.error(error.response.body)
} }
// TODO: stuff into DB if failed and retry later // TODO: stuff into DB if failed and retry later

View File

@@ -1,4 +1,5 @@
import { Booking } from '../db/booking' import { Booking } from '../db/booking'
import { log } from '../helpers/log'
const BOOKING_DATA_KEY = 'pfadiBussleBookingData' const BOOKING_DATA_KEY = 'pfadiBussleBookingData'
@@ -25,7 +26,7 @@ export function loadBookingData() {
try { try {
result = JSON.parse(dataAsString) result = JSON.parse(dataAsString)
} catch (e) { } catch (e) {
console.error(`localStorage ${BOOKING_DATA_KEY} has invalid data stored`) log.error(`localStorage ${BOOKING_DATA_KEY} has invalid data stored`)
} }
return result return result

View File

@@ -2,6 +2,7 @@ import { google } from 'googleapis'
import { getBaseURL } from '../helpers/url' import { getBaseURL } from '../helpers/url'
import { Booking } from '../db/booking' import { Booking } from '../db/booking'
import { getDays } from '../helpers/date' import { getDays } from '../helpers/date'
import { log } from '../helpers/log'
const calendarId = process.env.GOOGLE_CALENDAR_ID const calendarId = process.env.GOOGLE_CALENDAR_ID
let credentials: object let credentials: object
@@ -9,7 +10,7 @@ let credentials: object
try { try {
credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON) credentials = JSON.parse(process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON)
} catch (error) { } catch (error) {
console.error( log.error(
'Unable to parse process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON - invalid JSON?' 'Unable to parse process.env.GOOGLE_SERVICE_ACCOUNT_KEY_JSON - invalid JSON?'
) )
throw error throw error

View File

@@ -1,3 +1,5 @@
module.exports = { const { withAxiom } = require('next-axiom')
module.exports = withAxiom({
swcMinify: true, swcMinify: true,
} })

39
package-lock.json generated
View File

@@ -19,6 +19,7 @@
"mongoose": "6.3.8", "mongoose": "6.3.8",
"next": "12.1.6", "next": "12.1.6",
"next-auth": "4.6.1", "next-auth": "4.6.1",
"next-axiom": "^0.8.0",
"next-mdx-remote": "4.0.3", "next-mdx-remote": "4.0.3",
"nodemailer": "6.7.5", "nodemailer": "6.7.5",
"react": "18.2.0", "react": "18.2.0",
@@ -2726,6 +2727,14 @@
"url": "https://opencollective.com/core-js" "url": "https://opencollective.com/core-js"
} }
}, },
"node_modules/cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"dependencies": {
"node-fetch": "2.6.7"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -6768,6 +6777,20 @@
} }
} }
}, },
"node_modules/next-axiom": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-0.8.0.tgz",
"integrity": "sha512-lSgUHBhcSDR97uSoUVqrFiMIGuH47lR8x57oUzUn98r+aMo7FDgqcmNPtWkYZGATTrBfIt/ZmaCq6YBhNYuR/g==",
"dependencies": {
"cross-fetch": "^3.1.5"
},
"engines": {
"node": ">=15"
},
"peerDependencies": {
"next": "^12.1.4"
}
},
"node_modules/next-mdx-remote": { "node_modules/next-mdx-remote": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-4.0.3.tgz", "resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-4.0.3.tgz",
@@ -11266,6 +11289,14 @@
"integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==",
"dev": true "dev": true
}, },
"cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"requires": {
"node-fetch": "2.6.7"
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -14119,6 +14150,14 @@
"uuid": "^8.3.2" "uuid": "^8.3.2"
} }
}, },
"next-axiom": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/next-axiom/-/next-axiom-0.8.0.tgz",
"integrity": "sha512-lSgUHBhcSDR97uSoUVqrFiMIGuH47lR8x57oUzUn98r+aMo7FDgqcmNPtWkYZGATTrBfIt/ZmaCq6YBhNYuR/g==",
"requires": {
"cross-fetch": "^3.1.5"
}
},
"next-mdx-remote": { "next-mdx-remote": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-4.0.3.tgz", "resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-4.0.3.tgz",

View File

@@ -21,6 +21,7 @@
"mongoose": "6.3.8", "mongoose": "6.3.8",
"next": "12.1.6", "next": "12.1.6",
"next-auth": "4.6.1", "next-auth": "4.6.1",
"next-axiom": "^0.8.0",
"next-mdx-remote": "4.0.3", "next-mdx-remote": "4.0.3",
"nodemailer": "6.7.5", "nodemailer": "6.7.5",
"react": "18.2.0", "react": "18.2.0",

View File

@@ -1,3 +1,4 @@
export { reportWebVitals } from 'next-axiom'
import { useEffect } from 'react' import { useEffect } from 'react'
import { useSession, signIn, SessionProvider } from 'next-auth/react' import { useSession, signIn, SessionProvider } from 'next-auth/react'

View File

@@ -6,6 +6,7 @@ import { Booking } from '../../../../db/booking'
import { BILL_STATUS, MILAGE_TARIFS } from '../../../../db/enums' import { BILL_STATUS, MILAGE_TARIFS } from '../../../../db/enums'
import { getMilageMax } from '../../../../db/index' import { getMilageMax } from '../../../../db/index'
import { daysFormatFrontend } from '../../../../helpers/date' import { daysFormatFrontend } from '../../../../helpers/date'
import { log } from '../../../../helpers/log'
import { getBillTotal, createBill, patchBill } from '../../../../helpers/bill' import { getBillTotal, createBill, patchBill } from '../../../../helpers/bill'
import { getBookingStatus } from '../../../../helpers/booking' import { getBookingStatus } from '../../../../helpers/booking'
import { getServerSideBooking } from '../../../../lib/getServerSideProps' import { getServerSideBooking } from '../../../../lib/getServerSideProps'
@@ -109,7 +110,7 @@ function BookingBillPage({
setBooking(booking) setBooking(booking)
} catch (error) { } catch (error) {
setStoringError('Buchung konnte nicht gespeichert werden!') setStoringError('Buchung konnte nicht gespeichert werden!')
console.error('Failed to store booking', error) log.error('Failed to store booking', error)
} }
setStoringInProgress(false) setStoringInProgress(false)
} }
@@ -197,9 +198,8 @@ function BookingBillPage({
> >
- -
</button> </button>
<label className="flabel inline">{`Kostenpunkt ${ <label className="flabel inline">{`Kostenpunkt ${index + 1
index + 1 }`}</label>
}`}</label>
</div> </div>
<div className="ml-10 mb-3" key={`input{index}`}> <div className="ml-10 mb-3" key={`input{index}`}>
<Input <Input

View File

@@ -7,6 +7,7 @@ import { getServerSideBooking } from '../../../../lib/getServerSideProps'
import { Booking } from '../../../../db/booking' import { Booking } from '../../../../db/booking'
import { getBookingStatus, patchBooking } from '../../../../helpers/booking' import { getBookingStatus, patchBooking } from '../../../../helpers/booking'
import { daysFormatFrontend } from '../../../../helpers/date' import { daysFormatFrontend } from '../../../../helpers/date'
import { log } from '../../../../helpers/log'
import { BOOKING_STATUS } from '../../../../db/enums' import { BOOKING_STATUS } from '../../../../db/enums'
export const getServerSideProps = getServerSideBooking export const getServerSideProps = getServerSideBooking
@@ -30,7 +31,7 @@ function ShowBookingAdmin({ booking: bookingProp }: { booking: Booking }) {
setBooking(updatedBooking) setBooking(updatedBooking)
} catch (error) { } catch (error) {
setStoringBookingError('Buchung konnte nicht gespeichert werden.') setStoringBookingError('Buchung konnte nicht gespeichert werden.')
console.error('Failed to store booking', error) log.error('Failed to store booking', error)
} }
setStoringBooking(false) setStoringBooking(false)
} }

View File

@@ -1,6 +1,7 @@
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { Bill } from '../../../../db/bill' import { Bill } from '../../../../db/bill'
import { createBill, patchBill } from '../../../../db/index' import { createBill, patchBill } from '../../../../db/index'
import { log } from '../../../../helpers/log'
export default async function billHandler( export default async function billHandler(
req: NextApiRequest, req: NextApiRequest,
@@ -20,7 +21,7 @@ export default async function billHandler(
bill = await createBill(bookingUUID, req.body) bill = await createBill(bookingUUID, req.body)
res.status(200).json(bill) res.status(200).json(bill)
} catch (e) { } catch (e) {
console.error(e) log.error('Failed to store bill', e)
res.status(500).end(`Internal Server Error...Guru is meditating...`) res.status(500).end(`Internal Server Error...Guru is meditating...`)
return return
} }
@@ -30,7 +31,7 @@ export default async function billHandler(
bill = await patchBill(bookingUUID, req.body) bill = await patchBill(bookingUUID, req.body)
res.status(200).json(bill) res.status(200).json(bill)
} catch (e) { } catch (e) {
console.error(e) log.error('Failed to patch bill', e)
res.status(500).end(`Internal Server Error...Guru is meditating...`) res.status(500).end(`Internal Server Error...Guru is meditating...`)
return return
} }

View File

@@ -7,6 +7,7 @@ import {
sendBookingRejected, sendBookingRejected,
sendBookingCanceled, sendBookingCanceled,
} from '../../../../helpers/mail' } from '../../../../helpers/mail'
import { log } from '../../../../helpers/log'
function changedStatus( function changedStatus(
previous: Booking, previous: Booking,
@@ -72,7 +73,7 @@ export default async function userHandler(
res.status(200).json(current) res.status(200).json(current)
} catch (error) { } catch (error) {
console.error('failed patch booking', error) log.error('failed patch booking', error)
res.status(400).end(`Failed to save booking: ${error.message}`) res.status(400).end(`Failed to save booking: ${error.message}`)
} }
break break

View File

@@ -2,6 +2,7 @@ import { Error } from 'mongoose'
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { Booking } from '../../../db/booking' import { Booking } from '../../../db/booking'
import { createBooking } from '../../../db/index' import { createBooking } from '../../../db/index'
import { log } from '../../../helpers/log'
import { import {
sendReceivedBookingAdminMail, sendReceivedBookingAdminMail,
sendReceivedBookingBookerMail, sendReceivedBookingBookerMail,
@@ -21,20 +22,23 @@ export default async function userHandler(
booking = await createBooking(req.body) booking = await createBooking(req.body)
res.status(200).json(booking) res.status(200).json(booking)
} catch (e) { } catch (e) {
console.error(e)
if (e instanceof Error.ValidationError) { if (e instanceof Error.ValidationError) {
res.status(400).json({ message: e.message, errors: e.errors }) res.status(400).json({ message: e.message, errors: e.errors })
return return
} }
log.error('Failed to store booking', e)
res.status(500).end(`Internal Server Error...Guru is meditating...`) res.status(500).end(`Internal Server Error...Guru is meditating...`)
return return
} }
console.log(`received booking ${booking.uuid} from {booking.email}`) log.info(`received booking ${booking.uuid} from {booking.email}`)
await sendReceivedBookingAdminMail(booking) await sendReceivedBookingAdminMail(booking)
console.log(`send booking ${booking.uuid} received to admin`) log.info(`send booking ${booking.uuid} received to admin`, booking)
await sendReceivedBookingBookerMail(booking) await sendReceivedBookingBookerMail(booking)
console.log(`send booking ${booking.uuid} received to {booking.email}`) log.info(
`send booking ${booking.uuid} received to {booking.email}`,
booking
)
break break
default: default:
res.setHeader('Allow', ['POST']) res.setHeader('Allow', ['POST'])

View File

@@ -4,6 +4,7 @@ import { getServerSideBooking } from '../../../lib/getServerSideProps'
import { Booking } from '../../../db/booking' import { Booking } from '../../../db/booking'
import { BOOKING_STATUS } from '../../../db/enums' import { BOOKING_STATUS } from '../../../db/enums'
import { daysFormatFrontend } from '../../../helpers/date' import { daysFormatFrontend } from '../../../helpers/date'
import { log } from '../../../helpers/log'
import { getBookingStatus, cancelBooking } from '../../../helpers/booking' import { getBookingStatus, cancelBooking } from '../../../helpers/booking'
export const getServerSideProps = getServerSideBooking export const getServerSideProps = getServerSideBooking
@@ -34,7 +35,7 @@ export default function ShowBooking({
setStoringBookingError( setStoringBookingError(
'Buchung konnte nicht storniert werden. Schreiben Sie uns eine E-Mail!' 'Buchung konnte nicht storniert werden. Schreiben Sie uns eine E-Mail!'
) )
console.error('Failed to store booking', error) log.error('Failed to store booking', error)
} }
setStoringBooking(false) setStoringBooking(false)
} }
@@ -53,16 +54,16 @@ export default function ShowBooking({
{[BOOKING_STATUS.CONFIRMED, BOOKING_STATUS.REQUESTED].includes( {[BOOKING_STATUS.CONFIRMED, BOOKING_STATUS.REQUESTED].includes(
booking.status booking.status
) && ( ) && (
<div className="my-6"> <div className="my-6">
<button <button
onClick={onCancelBooking} onClick={onCancelBooking}
className="btn btn-red" className="btn btn-red"
disabled={storingBooking} disabled={storingBooking}
> >
Buchung Stornieren Buchung Stornieren
</button> </button>
</div> </div>
)} )}
</Layout> </Layout>
) )
} }