packages feed

hotel-california 0.0.6.2 → 0.1.0.0

raw patch · 6 files changed

+115/−55 lines, 6 filesdep −hs-opentelemetry-vendor-honeycombdep ~hs-opentelemetry-apidep ~hs-opentelemetry-sdksetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies removed: hs-opentelemetry-vendor-honeycomb

Dependency ranges changed: hs-opentelemetry-api, hs-opentelemetry-sdk

API changes (from Hackage documentation)

+ HotelCalifornia.Tracing: TracingStatus :: Bool -> TracingStatus
+ HotelCalifornia.Tracing: [tracingEnabled] :: TracingStatus -> Bool
+ HotelCalifornia.Tracing: data TracingStatus
+ HotelCalifornia.Tracing: otelTracingEnabled :: IO Bool
- HotelCalifornia.Tracing: withGlobalTracing :: MonadUnliftIO m => (Maybe HoneycombTarget -> m a) -> m a
+ HotelCalifornia.Tracing: withGlobalTracing :: MonadUnliftIO m => (TracingStatus -> m a) -> m a

Files

CHANGELOG.md view
@@ -8,6 +8,22 @@  ## Unreleased +- [#23](https://github.com/parsonsmatt/hotel-california/pull/23)+    - Tracing is now only initialized when an exporter is configured;+      otherwise tracing is bypassed entirely. Honeycomb is no longer consulted+      to decide whether tracing is on. Following the [OpenTelemetry+      environment variable specification](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/):+        - `OTEL_SDK_DISABLED=true` (case-insensitive) disables tracing.+        - `OTEL_TRACES_EXPORTER=none` disables tracing; any other non-empty+          value enables it.+        - Otherwise, tracing is enabled iff any `OTEL_EXPORTER_*` environment+          variable is set with a non-empty value.+        - Environment variables set to the empty string are treated as unset.+    - Breaking change: the callback to `withGlobalTracing` now receives a+      `TracingStatus` record (instead of `Maybe HoneycombTarget`), which+      carries a `tracingEnabled` field. Downstream consumers that want+      Honeycomb trace links can set those up themselves.+ ## 0.0.6.2 - 2026-06-25  - [#25](https://github.com/parsonsmatt/hotel-california/pull/25)
README.md view
@@ -39,6 +39,11 @@   [`hs-opentelemetry-sdk`](https://hackage.haskell.org/package/hs-opentelemetry-sdk)   for more information +Tracing is opt-in: it is enabled when `OTEL_TRACES_EXPORTER` is set (to+anything other than `none`), or when any `OTEL_EXPORTER_*` environment+variable is set with a non-empty value. Setting `OTEL_SDK_DISABLED=true`+disables tracing regardless of any other configuration.+ # Background/FAQ  ## Lol what's up with the name
Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
app/Main.hs view
@@ -1,11 +1,11 @@ module Main where  import Data.Version (showVersion)-import Paths_hotel_california (version) import HotelCalifornia.Exec-import HotelCalifornia.Tracing (withGlobalTracing)+import HotelCalifornia.Tracing (TracingStatus (..), withGlobalTracing) import Options.Applicative import Options.Applicative.Help.Pretty (Doc, vsep)+import Paths_hotel_california (version)  data Command = Command     { commandGlobalOptions :: GlobalOptions@@ -18,49 +18,58 @@     = Exec ExecArgs  programDescription :: Doc-programDescription = vsep-  [ "`hotel-california` is a tool for OTel tracing of shell scripts, inspired by `otel-cli`."-  , "For help with a command, say `hotel COMMAND --help`. Currently, the only supported command is `exec`."-  , ""-  , "Check out the repository any time you like at https://github.com/parsonsmatt/hotel-california."-  ]+programDescription =+    vsep+        [ "`hotel-california` is a tool for OTel tracing of shell scripts, inspired by `otel-cli`."+        , "For help with a command, say `hotel COMMAND --help`. Currently, the only supported command is `exec`."+        , ""+        , "Check out the repository any time you like at https://github.com/parsonsmatt/hotel-california."+        ]  optionsParser :: ParserInfo Command optionsParser =     info' parser' programDescription   where-  -- thanks danidiaz for the blog post+    -- thanks danidiaz for the blog post     info' :: Parser a -> Doc -> ParserInfo a-    info' p descDoc = info-        (helper <*> p)-        (fullDesc <> progDescDoc (Just descDoc) <> noIntersperse)+    info' p descDoc =+        info+            (helper <*> p)+            (fullDesc <> progDescDoc (Just descDoc) <> noIntersperse)      parser' :: Parser Command     parser' =         Command             <$> generalOptionsParser             <*> subCommandParser-            <**> simpleVersioner (showVersion version)+                <**> simpleVersioner (showVersion version)      generalOptionsParser =         pure GlobalOptions      subCommandParser :: Parser SubCommand     subCommandParser =-        subparser $ foldMap command'-                    [ ("exec", "Execute the given command with tracing enabled", Exec <$> parseExecArgs)-                    ]+        subparser $+            foldMap+                command'+                [+                    ( "exec"+                    , "Execute the given command with tracing enabled"+                    , Exec <$> parseExecArgs+                    )+                ] -    command' (cmdName,desc,parser) =+    command' (cmdName, desc, parser) =         command cmdName (info' parser desc)  main :: IO () main = do-    withGlobalTracing $ \mTarget -> do-        let parserPrefs = defaultPrefs{ prefMultiSuffix = "..." }-        Command {..} <- customExecParser parserPrefs optionsParser+    withGlobalTracing $ \tracingStatus -> do+        let+            parserPrefs = defaultPrefs{prefMultiSuffix = "..."}+        Command{..} <- customExecParser parserPrefs optionsParser         case commandSubCommand of             Exec execArgs ->-                case mTarget of-                    Just _target -> runExecArgs execArgs-                    Nothing -> runNoTracing $ execArgsSubprocess execArgs+                if tracingStatus.tracingEnabled+                    then runExecArgs execArgs+                    else runNoTracing $ execArgsSubprocess execArgs
hotel-california.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           hotel-california-version:        0.0.6.2+version:        0.1.0.0 description:    Please see the README on GitHub at <https://github.com/parsonsmatt/hotel-california#readme> homepage:       https://github.com/parsonsmatt/hotel-california#readme bug-reports:    https://github.com/parsonsmatt/hotel-california/issues@@ -77,12 +77,11 @@     , bytestring     , directory     , filepath-    , hs-opentelemetry-api >=0.1.0.0+    , hs-opentelemetry-api >=0.3.0.0     , hs-opentelemetry-exporter-otlp     , hs-opentelemetry-propagator-w3c-    , hs-opentelemetry-sdk >=0.0.3.6+    , hs-opentelemetry-sdk >=0.1.0.1     , hs-opentelemetry-utils-exceptions-    , hs-opentelemetry-vendor-honeycomb     , http-types     , optparse-applicative     , posix-escape@@ -143,12 +142,11 @@     , directory     , filepath     , hotel-california-    , hs-opentelemetry-api >=0.1.0.0+    , hs-opentelemetry-api >=0.3.0.0     , hs-opentelemetry-exporter-otlp     , hs-opentelemetry-propagator-w3c-    , hs-opentelemetry-sdk >=0.0.3.6+    , hs-opentelemetry-sdk >=0.1.0.1     , hs-opentelemetry-utils-exceptions-    , hs-opentelemetry-vendor-honeycomb     , http-types     , optparse-applicative     , posix-escape@@ -210,12 +208,11 @@     , directory     , filepath     , hotel-california-    , hs-opentelemetry-api >=0.1.0.0+    , hs-opentelemetry-api >=0.3.0.0     , hs-opentelemetry-exporter-otlp     , hs-opentelemetry-propagator-w3c-    , hs-opentelemetry-sdk >=0.0.3.6+    , hs-opentelemetry-sdk >=0.1.0.1     , hs-opentelemetry-utils-exceptions-    , hs-opentelemetry-vendor-honeycomb     , http-types     , optparse-applicative     , posix-escape
src/HotelCalifornia/Tracing.hs view
@@ -6,9 +6,10 @@     ) where  import Control.Monad-import Data.ByteString.Char8 qualified as BS8+import Data.Char (toLower)+import Data.List (isPrefixOf)+import Data.Maybe (isJust) import Data.Text (Text)-import Data.Time import HotelCalifornia.Tracing.TraceParent import OpenTelemetry.Context as Context hiding (lookup) import OpenTelemetry.Context.ThreadLocal (attachContext)@@ -23,7 +24,7 @@     , inSpan''     ) import OpenTelemetry.Trace qualified as Trace-import OpenTelemetry.Vendor.Honeycomb qualified as Honeycomb+import System.Environment (getEnvironment) import UnliftIO  -- | Initialize the global tracing provider for the application and run an action@@ -31,29 +32,61 @@ --   up the provider afterwards. -- --   This also sets up an empty context (creating a new trace ID).-withGlobalTracing-    :: (MonadUnliftIO m) => (Maybe Honeycomb.HoneycombTarget -> m a) -> m a+--+--   The callback receives a 'TracingStatus' describing whether tracing was+--   actually initialized; see 'tracingEnabled'.+withGlobalTracing :: (MonadUnliftIO m) => (TracingStatus -> m a) -> m a withGlobalTracing act = do     void $ attachContext Context.empty     liftIO setParentSpanFromEnvironment-    withTracer $ \_ -> do-        -- note: this is not in a span since we don't have a root span yet so it-        -- would not wind up in the trace in a helpful way anyway-        mTarget <--            Honeycomb.getOrInitializeHoneycombTargetInContext initializationTimeout-                `catch` \(e :: SomeException) -> do-                    -- we are too early in initialization to be able to use a normal logger,-                    -- but this needs to get out somehow.-                    ---                    -- honeycomb links are not load-bearing, so we let them just not come-                    -- up if the API fails.-                    liftIO . BS8.hPutStrLn stderr $-                        "error setting up Honeycomb trace links: " <> (BS8.pack $ displayException e)-                    pure Nothing+    enabled <- liftIO otelTracingEnabled+    if enabled+        then withTracer $ \_ -> act TracingStatus{tracingEnabled = True}+        else act TracingStatus{tracingEnabled = False} -        act mTarget+-- | The result of setting up tracing, passed to the callback of+--   'withGlobalTracing'.+data TracingStatus = TracingStatus+    { tracingEnabled :: Bool+    -- ^ 'True' when an exporter is configured (see 'otelTracingEnabled') and+    --   tracing has been initialized, and 'False' otherwise -- in which case+    --   the caller should bypass tracing.+    }++-- | Decide whether tracing should be initialized, following the OpenTelemetry+--   [environment variable specification](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/)+--   where practical:+--+--   * @OTEL_SDK_DISABLED=true@ (case-insensitive) disables tracing.+--   * @OTEL_TRACES_EXPORTER=none@ disables tracing; any other non-empty value+--     enables it.+--   * Otherwise, tracing is enabled iff any @OTEL_EXPORTER_*@ environment+--     variable is set with a non-empty value.+--+--   The spec would have tracing enabled unconditionally, with+--   @OTEL_TRACES_EXPORTER@ defaulting to an OTLP exporter aimed at+--   @localhost@; since running with no collector at all is the common case+--   for a CLI tool, we deviate and treat exporter configuration as opt-in.+--+--   Per the spec, an environment variable set to the empty string is treated+--   the same as unset.+otelTracingEnabled :: IO Bool+otelTracingEnabled = do+    env <- getEnvironment+    let+        getVar key = do+            value <- lookup key env+            guard $ not $ null value+            pure $ map toLower value+        sdkDisabled = getVar "OTEL_SDK_DISABLED" == Just "true"+        tracesExporter = getVar "OTEL_TRACES_EXPORTER"+        hasOtelExporterVar = any isOtelExporterVar env+    pure $+        not sdkDisabled+            && tracesExporter /= Just "none"+            && (isJust tracesExporter || hasOtelExporterVar)   where-    initializationTimeout = secondsToNominalDiffTime 1+    isOtelExporterVar (k, v) = "OTEL_EXPORTER_" `isPrefixOf` k && not (null v)  globalTracer :: (MonadIO m) => m Tracer globalTracer =@@ -76,7 +109,6 @@ inSpan :: (MonadUnliftIO m) => Text -> m a -> m a inSpan spanName =     inSpanWith spanName defaultSpanArguments- withTracer :: (MonadUnliftIO m) => (TracerProvider -> m a) -> m a withTracer =     bracket (liftIO initializeGlobalTracerProvider) shutdown