diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+# log-base-0.12.1.0 (2025-06-26)
+* Add utility function to log unhandled exceptions.
+
 # log-base-0.12.0.1 (2023-03-14)
 * Add support for GHC 9.6.
 
diff --git a/log-base.cabal b/log-base.cabal
--- a/log-base.cabal
+++ b/log-base.cabal
@@ -1,5 +1,6 @@
+cabal-version:       3.0
 name:                log-base
-version:             0.12.0.1
+version:             0.12.1.0
 synopsis:            Structured logging solution (base package)
 
 description:         A library that provides a way to record structured log
@@ -9,7 +10,7 @@
 
 
 homepage:            https://github.com/scrive/log
-license:             BSD3
+license:             BSD-3-Clause
 license-file:        LICENSE
 author:              Scrive AB
 maintainer:          Andrzej Rybczak <andrzej@rybczak.net>,
@@ -19,13 +20,12 @@
 copyright:           Scrive AB
 category:            System
 build-type:          Simple
-cabal-version:       >=1.10
 extra-source-files:  CHANGELOG.md, README.md
-tested-with:         GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.7 || ==9.4.4 || ==9.6.1
+tested-with:         GHC == { 8.10.7, 9.0.2, 9.2.8, 9.4.8, 9.6.7, 9.8.4, 9.10.2, 9.12.2 }
 
-Source-repository head
-  Type:     git
-  Location: https://github.com/scrive/log.git
+source-repository head
+  type:     git
+  location: https://github.com/scrive/log.git
 
 library
   exposed-modules:     Log,
diff --git a/src/Log/Monad.hs b/src/Log/Monad.hs
--- a/src/Log/Monad.hs
+++ b/src/Log/Monad.hs
@@ -6,6 +6,7 @@
   , InnerLogT
   , LogT(..)
   , runLogT
+  , logExceptions
   , mapLogT
   , logMessageIO
   , getLoggerIO
@@ -66,6 +67,25 @@
 , leMaxLogLevel = maxLogLevel
 } -- We can't do synchronisation here, since 'runLogT' can be invoked
   -- quite often from the application (e.g. on every request).
+
+-- | Ensure uncaught exceptions get logged.
+-- Convenient to compose right after `runLogT` so any exception
+-- will show up.
+logExceptions :: (MonadBaseControl IO m, MonadLog m) => m a -> m a
+logExceptions f =
+  liftedCatch f $ \(SomeException e) -> do
+      logAttention "Uncaught exception" $ object ["exception" .= show e]
+      liftBase $ E.throwIO e
+
+-- Generalized version of catch taken from `lifted-base`.
+liftedCatch :: (MonadBaseControl IO m, Exception e)
+      => m a       -- ^ The computation to run.
+      -> (e -> m a) -- ^ Handler to invoke if an exception is raised.
+      -> m a
+liftedCatch a handler = control $ \runInIO ->
+  E.catch
+    (runInIO a)
+    (runInIO . handler)
 
 -- | Transform the computation inside a 'LogT'.
 mapLogT :: (m a -> n b) -> LogT m a -> LogT n b
