diff --git a/Blammo.cabal b/Blammo.cabal
--- a/Blammo.cabal
+++ b/Blammo.cabal
@@ -1,6 +1,6 @@
 cabal-version:   1.18
 name:            Blammo
-version:         1.1.1.2
+version:         1.1.2.0
 license:         MIT
 license-file:    LICENSE
 maintainer:      Freckle Education
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
-## [_Unreleased_](https://github.com/freckle/blammo/compare/v1.1.1.2...main)
+## [_Unreleased_](https://github.com/freckle/blammo/compare/v1.1.2.0...main)
+
+## [v1.1.2.0](https://github.com/freckle/blammo/compare/v1.1.1.2...v1.1.2.0)
+
+- Add `Blammo.Logging.LogSettings.LogLevels`
 
 ## [v1.1.1.2](https://github.com/freckle/blammo/compare/v1.1.1.1...v1.1.1.2)
 
diff --git a/src/Blammo/Logging/LogSettings/LogLevels.hs b/src/Blammo/Logging/LogSettings/LogLevels.hs
--- a/src/Blammo/Logging/LogSettings/LogLevels.hs
+++ b/src/Blammo/Logging/LogSettings/LogLevels.hs
@@ -52,6 +52,7 @@
   , LogLevel(..)
   , newLogLevels
   , readLogLevels
+  , showLogLevels
   , shouldLogLevel
   , defaultLogLevels
   ) where
@@ -103,6 +104,20 @@
   "warn" -> LevelWarn
   "error" -> LevelError
   _ -> LevelOther t
+
+showLogLevels :: LogLevels -> String
+showLogLevels LogLevels {..} =
+  unpack $ T.intercalate "," $ showLogLevel llDefaultLevel : map
+    (\(s, l) -> s <> ":" <> showLogLevel l)
+    (Map.toList llSourceLevels)
+
+showLogLevel :: LogLevel -> Text
+showLogLevel = \case
+  LevelDebug -> "debug"
+  LevelInfo -> "info"
+  LevelWarn -> "warn"
+  LevelError -> "error"
+  LevelOther t -> t
 
 shouldLogLevel :: LogLevels -> LogSource -> LogLevel -> Bool
 shouldLogLevel LogLevels {..} source = (`lgte` minLevel)
diff --git a/tests/Blammo/Logging/LogSettings/LogLevelsSpec.hs b/tests/Blammo/Logging/LogSettings/LogLevelsSpec.hs
--- a/tests/Blammo/Logging/LogSettings/LogLevelsSpec.hs
+++ b/tests/Blammo/Logging/LogSettings/LogLevelsSpec.hs
@@ -1,5 +1,3 @@
-{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
-
 module Blammo.Logging.LogSettings.LogLevelsSpec
   ( spec
   ) where
@@ -31,11 +29,30 @@
       readLogLevels "foo:warn,info" `shouldSatisfy` isRight
       readLogLevels "foo:warn,info,foo:warn" `shouldSatisfy` isRight
 
+  describe "showLogLevels" $ do
+    it "shows a simple log levels" $ do
+      let ll = newLogLevels LevelWarn []
+
+      showLogLevels ll `shouldBe` "warn"
+
+    it "shows complex log levels in normalized order and casing" $ do
+      -- Using readLogLevel here so we can highlight how it gets normalized
+      let ell = readLogLevels "foo:WARN,info,bar:debug"
+
+      fmap showLogLevels ell `shouldBe` Right "info,bar:debug,foo:warn"
+
+    -- This is a compromise vs using a proper property because it was just too
+    -- complex to make Arbitrary LogLevels
+    it "round-trips through readLogLevels" $ do
+      let ll = newLogLevels LevelWarn [("foo", LevelInfo), ("bar", LevelDebug)]
+
+      readLogLevels (showLogLevels ll) `shouldBe` Right ll
+
   describe "shouldLogLevel" $ do
     it "uses the default log level for unknown sources" $ do
       let
-        Right ll1 = readLogLevels "warn"
-        Right ll2 = readLogLevels "warn,foo:debug"
+        ll1 = newLogLevels LevelWarn []
+        ll2 = newLogLevels LevelWarn [("foo", LevelDebug)]
 
       shouldLogLevel ll1 "foo" LevelInfo `shouldBe` False
       shouldLogLevel ll1 "bar" LevelInfo `shouldBe` False
@@ -44,7 +61,9 @@
       shouldLogLevel ll2 "bar" LevelInfo `shouldBe` False
 
     it "can override multiple sources" $ do
-      let Right ll = readLogLevels "debug,Amazonka:warn,SQL:info"
+      let
+        ll =
+          newLogLevels LevelDebug [("Amazonka", LevelWarn), ("SQL", LevelInfo)]
 
       shouldLogLevel ll "app" LevelDebug `shouldBe` True
       shouldLogLevel ll "Amazonka" LevelInfo `shouldBe` False
