packages feed

instana-haskell-trace-sdk 0.10.1.0 → 0.10.2.0

raw patch · 8 files changed

+229/−53 lines, 8 filesdep +safePVP ok

version bump matches the API change (PVP)

Dependencies added: safe

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,8 @@ # Changelog for instana-haskell-trace-sdk +## 0.10.2.0+- Remove dependency on sbin and awk in containers.+ ## 0.10.1.0 - Fix: Remove obsolete check for Server header when connecting to the Instana host agent. 
README.md view
@@ -15,7 +15,7 @@  ``` extra-deps:-- instana-haskell-trace-sdk-0.10.1.0+- instana-haskell-trace-sdk-0.10.2.0 ```  Depending on the stack resolver you use, you might also need to add `aeson-extra` to your extra-deps:
instana-haskell-trace-sdk.cabal view
@@ -1,5 +1,5 @@ name:           instana-haskell-trace-sdk-version:        0.10.1.0+version:        0.10.2.0 synopsis:       SDK for adding custom Instana tracing support to Haskell applications. description:    Please also see the README on Github at <https://github.com/instana/haskell-trace-sdk#readme> homepage:       https://www.instana.com/@@ -47,13 +47,13 @@     , http-client-tls     , http-types     , network-    , process     , random     , regex-base     , regex-compat     , regex-pcre     , regex-tdfa     , retry+    , safe     , scientific     , stm     , sysinfo@@ -87,6 +87,7 @@       Instana.SDK.Internal.AgentConnection.AgentReady       Instana.SDK.Internal.AgentConnection.Announce       Instana.SDK.Internal.AgentConnection.ConnectLoop+      Instana.SDK.Internal.AgentConnection.DefaultGatewayIp       Instana.SDK.Internal.AgentConnection.Json.AnnounceResponse       Instana.SDK.Internal.AgentConnection.Json.Util       Instana.SDK.Internal.AgentConnection.Paths@@ -168,6 +169,7 @@     , regex-compat     , regex-pcre     , regex-tdfa+    , safe     , scientific     , text     , unordered-containers@@ -175,6 +177,7 @@     , wai   other-modules:       -- the actual tests+      Instana.SDK.Internal.AgentConnection.DefaultGatewayIpTest       Instana.SDK.Internal.AgentConnection.SchedFileTest       Instana.SDK.Internal.ConfigTest       Instana.SDK.Internal.IdTest@@ -190,6 +193,7 @@       Instana.SDK.TracingHeadersTest       -- modules under test       Instana.SDK.Internal.Config+      Instana.SDK.Internal.AgentConnection.DefaultGatewayIp       Instana.SDK.Internal.AgentConnection.SchedFile       Instana.SDK.Internal.Id       Instana.SDK.Internal.Logging
src/Instana/SDK/Internal/AgentConnection/AgentHostLookup.hs view
@@ -10,26 +10,23 @@     ) where  -import qualified Control.Concurrent.STM                           as STM-import           Control.Exception                                (SomeException,-                                                                   catch)-import           Data.Char                                        (isSpace)-import qualified Data.List                                        as List-import qualified Network.HTTP.Client                              as HTTP-import qualified Network.HTTP.Types.Status                        as Status-import           System.Exit                                      (ExitCode (ExitSuccess))-import           System.Log.Logger                                (debugM)-import           System.Process                                   as Process+import qualified Control.Concurrent.STM                                as STM+import           Control.Exception                                     (SomeException,+                                                                        catch)+import qualified Network.HTTP.Client                                   as HTTP+import qualified Network.HTTP.Types.Status                             as Status+import           System.Log.Logger                                     (debugM) -import qualified Instana.SDK.Internal.AgentConnection.Announce    as Announce-import           Instana.SDK.Internal.AgentConnection.ProcessInfo (ProcessInfo)-import qualified Instana.SDK.Internal.Config                      as InternalConfig-import           Instana.SDK.Internal.Context                     (ConnectionState (..),-                                                                   InternalContext)-import qualified Instana.SDK.Internal.Context                     as InternalContext-import           Instana.SDK.Internal.Logging                     (instanaLogger)-import qualified Instana.SDK.Internal.Retry                       as Retry-import qualified Instana.SDK.Internal.URL                         as URL+import qualified Instana.SDK.Internal.AgentConnection.Announce         as Announce+import           Instana.SDK.Internal.AgentConnection.DefaultGatewayIp (extractDefaultGatewayIp)+import           Instana.SDK.Internal.AgentConnection.ProcessInfo      (ProcessInfo)+import qualified Instana.SDK.Internal.Config                           as InternalConfig+import           Instana.SDK.Internal.Context                          (ConnectionState (..),+                                                                        InternalContext)+import qualified Instana.SDK.Internal.Context                          as InternalContext+import           Instana.SDK.Internal.Logging                          (instanaLogger)+import qualified Instana.SDK.Internal.Retry                            as Retry+import qualified Instana.SDK.Internal.URL                              as URL   type SuccessfullHost = (String, Int)@@ -143,15 +140,26 @@ readDefaultGateway :: IO (Either String String) readDefaultGateway = do   let-    cmd = "/sbin/ip route | awk '/default/ { print $3 }'"-    stdIn = ""-  (exitCode, stdOut, stdErr) <--    Process.readCreateProcessWithExitCode (Process.shell cmd) stdIn-  if exitCode /= ExitSuccess || stdErr /= ""-  then-    return $ Left $ "Failed to retrieve default gateway: " ++ stdErr-  else-    return $ Right $ trim stdOut-  where-    trim = List.dropWhileEnd isSpace . dropWhile isSpace-+    routeFilePath = "/proc/self/net/route"+  catch+    ( do+        routeFileContent <- readFile routeFilePath+        let+          defaultGatewayIpM = extractDefaultGatewayIp routeFileContent+        case defaultGatewayIpM of+          Just defaultGatewayIp -> do+            debugM instanaLogger $+              "Determined default gateway IP: " ++ defaultGatewayIp+            return $ Right defaultGatewayIp+          Nothing ->+            return $+              Left $+                "Failed to parse default gateway IP from " ++ routeFilePath ++ "."+    )+    (\(e :: SomeException) -> do+      return $+        Left $+          "Failed to read " ++ routeFilePath +++          " to determine the default gateway IP: " +++          show e+    )
+ src/Instana/SDK/Internal/AgentConnection/DefaultGatewayIp.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-|+Module      : Instana.SDK.Internal.AgentConnection.DefaultGatewayIp+Description : Extracts the default gateway IP from the content of /proc/self/net/route.+-}+module Instana.SDK.Internal.AgentConnection.DefaultGatewayIp+    ( extractDefaultGatewayIp+    ) where++import           Control.Monad (join)+import qualified Data.List     as List+import           Data.Text     (Text)+import qualified Data.Text     as T+import           Numeric       (readHex)+import           Safe          (atMay)+++-- |Parses the content of /proc/self/net/route to retrieve the IP of the default+-- gateway.+extractDefaultGatewayIp :: String -> Maybe String+extractDefaultGatewayIp routeFileContent =+  let+    allLines = lines routeFileContent+    linesAsFields = map (\l -> T.splitOn "\t" $ T.pack l) allLines+    lineWithDefaultGateway = List.find isDefaultGatewayLine linesAsFields+    ip = join $ fmap extractIpFromFields lineWithDefaultGateway+  in+  fmap T.unpack ip+++isDefaultGatewayLine :: [Text] -> Bool+isDefaultGatewayLine fields =+  let+    field2 = atMay fields 1+    lenField3 = fmap T.length $ atMay fields 2+  in+  length fields >= 3 &&+    field2 == Just "00000000" &&+    lenField3 == Just 8+++extractIpFromFields :: [Text] -> Maybe Text+extractIpFromFields fields =+  fmap convertHexStringToIp $ atMay fields 2+++convertHexStringToIp :: Text -> Text+convertHexStringToIp hexstring =+  let+    o1 = substringLength2 6 hexstring+    o2 = substringLength2 4 hexstring+    o3 = substringLength2 2 hexstring+    o4 = T.take 2 hexstring+  in+  T.intercalate "." $ map hexstringToDecimal [o1, o2, o3, o4]+++substringLength2 :: Int -> Text -> Text+substringLength2 start =+  T.take 2 . T.drop start+++hexstringToDecimal :: Text -> Text+hexstringToDecimal hexstring =+  let+    result = readHex $ T.unpack hexstring+  in+  case result of+      (x,_):_ -> T.pack $ show (x :: Int)+      _       -> "0"
test/integration/Instana/SDK/IntegrationTest/HttpHelper.hs view
@@ -45,15 +45,15 @@ --    agent to connect to with fibonacci backoff). -- 3) When this happens, the first attempt to talk to 127.0.0.1:1302 fails. -- 4) Next, the SDK attempts to talk to an agent over the default gateway.--- 5) This never happens locally (at least not on MacOS), as there is no---    /sbin/ip executable present--- 6) On Travis (or more generally on most Linux systems), the SDK actually---    tries the default gateway because that executable _is_ present. It will+-- 5) This never happens locally (at least not on MacOS), since the file+--    /proc/self/net/route does not exist.+-- 6) On CircleCI (or more generally on most Linux systems), the SDK actually+--    tries the default gateway because that file _is_ present. It will --    also find a default gateway (let's say, for example, 10.20.0.1). -- 7) That host is reachable so an HTTP request to 10.20.0.1:1302 is attempted --    (1302 is the configured agent port in the integration tests). -- 8) If something exists at 10.20.0.1:1302 it never sends a response. Or there---    is nothing there but somehow the request does not fail immediately.+--    is nothing there but the request only fails after the connection timeout. --    Either way, trying this HTTP request eats up around 5 seconds. Why 5 --    seconds? 5 seconds is: --    a) the timeout the SDK sets itself (see Instana/SDK/SDK.hs, value for
+ test/unit/Instana/SDK/Internal/AgentConnection/DefaultGatewayIpTest.hs view
@@ -0,0 +1,88 @@+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE OverloadedStrings #-}+module Instana.SDK.Internal.AgentConnection.DefaultGatewayIpTest (allTests) where+++import           Test.HUnit++import           Instana.SDK.Internal.AgentConnection.DefaultGatewayIp (extractDefaultGatewayIp)+++allTests :: Test+allTests =+  TestList+    [ TestLabel "shouldExtractDefaultGatewayIpFromFile" shouldExtractDefaultGatewayIpFromFile+    , TestLabel "shouldNotExtractFromEmptyFile" shouldNotExtractFromEmptyFile+    , TestLabel "shouldNotExtractFromLinesWithTooFewFields" shouldNotExtractFromLinesWithTooFewFields+    , TestLabel "shouldNotExtractIfNoLineHas8Zeroes" shouldNotExtractIfNoLineHas8Zeroes+    , TestLabel "shouldNotExtractIfThirdFieldHasWrongLength" shouldNotExtractIfThirdFieldHasWrongLength+    , TestLabel "shouldCopeWithThirdFieldNotAHexString" shouldCopeWithThirdFieldNotAHexString+    ]+++shouldExtractDefaultGatewayIpFromFile :: Test+shouldExtractDefaultGatewayIpFromFile =+  let+    defaultGatewayIp =+      extractDefaultGatewayIp $+        "Iface\tDestination\tGateway\tFlags\tRefCnt\tUse\tMetricMask\tMTU\tWindow\tIRTT\n" +++        "eth0\t0000F1AC\t00000000\t0001\t0\t0\t0\t0000FFFF0\t0\t0\n" +++        "eth0\t00000000\t010011AC\t0003\t0\t0\t0\t000000000\t0\t0\n" +++        "eth0\t000011AC\t00000000\t0001\t0\t0\t0\t0000FFFF0\t0\t0"+  in+  TestCase $+    assertEqual "default gateway IP" (Just "172.17.0.1") defaultGatewayIp+++shouldNotExtractFromEmptyFile :: Test+shouldNotExtractFromEmptyFile =+  let+    defaultGatewayIp = extractDefaultGatewayIp ""+  in+  TestCase $+    assertEqual "default gateway IP" Nothing defaultGatewayIp+++shouldNotExtractFromLinesWithTooFewFields :: Test+shouldNotExtractFromLinesWithTooFewFields =+  let+    defaultGatewayIp =+      extractDefaultGatewayIp $+        "Iface\tDestination\n" +++        "eth0\t00000000"+  in+  TestCase $+    assertEqual "default gateway IP" Nothing defaultGatewayIp+++shouldNotExtractIfNoLineHas8Zeroes :: Test+shouldNotExtractIfNoLineHas8Zeroes =+  let+    defaultGatewayIp =+      extractDefaultGatewayIp $+        "eth0\t00009000\t010011AC\t0003\t0\t0\t0\t000000000\t0\t0"+  in+  TestCase $+    assertEqual "default gateway IP" Nothing defaultGatewayIp+++shouldNotExtractIfThirdFieldHasWrongLength :: Test+shouldNotExtractIfThirdFieldHasWrongLength =+  let+    defaultGatewayIp =+      extractDefaultGatewayIp $+        "eth0\t00000000\t010011A\t0003\t0\t0\t0\t000000000\t0\t0"+  in+  TestCase $+    assertEqual "default gateway IP" Nothing defaultGatewayIp+++shouldCopeWithThirdFieldNotAHexString :: Test+shouldCopeWithThirdFieldNotAHexString =+  let+    defaultGatewayIp =+      extractDefaultGatewayIp $+        "eth0\t00000000\tghijklmn\t0003\t0\t0\t0\t000000000\t0\t0"+  in+  TestCase $+    assertEqual "default gateway IP" (Just "0.0.0.0") defaultGatewayIp
test/unit/Main.hs view
@@ -1,19 +1,20 @@ module Main where  -import qualified Instana.SDK.Internal.AgentConnection.SchedFileTest as SchedFileTest-import qualified Instana.SDK.Internal.ConfigTest                    as ConfigTest-import qualified Instana.SDK.Internal.IdTest                        as IdTest-import qualified Instana.SDK.Internal.LoggingTest                   as LoggingTest-import qualified Instana.SDK.Internal.Metrics.CompressionTest       as MetricsCompressionTest-import qualified Instana.SDK.Internal.Metrics.DeltasTest            as MetricsDeltasTest-import qualified Instana.SDK.Internal.SecretsTest                   as SecretsTest-import qualified Instana.SDK.Internal.ServerTimingTest              as ServerTimingTest-import qualified Instana.SDK.Internal.SpanStackTest                 as SpanStackTest-import qualified Instana.SDK.Internal.W3CTraceContextTest           as W3CTraceContextTest-import qualified Instana.SDK.SpanDataTest                           as SpanDataTest-import qualified Instana.SDK.SpanTest                               as SpanTest-import qualified Instana.SDK.TracingHeadersTest                     as TracingHeadersTest+import qualified Instana.SDK.Internal.AgentConnection.DefaultGatewayIpTest as DefaultGatewayIpTest+import qualified Instana.SDK.Internal.AgentConnection.SchedFileTest        as SchedFileTest+import qualified Instana.SDK.Internal.ConfigTest                           as ConfigTest+import qualified Instana.SDK.Internal.IdTest                               as IdTest+import qualified Instana.SDK.Internal.LoggingTest                          as LoggingTest+import qualified Instana.SDK.Internal.Metrics.CompressionTest              as MetricsCompressionTest+import qualified Instana.SDK.Internal.Metrics.DeltasTest                   as MetricsDeltasTest+import qualified Instana.SDK.Internal.SecretsTest                          as SecretsTest+import qualified Instana.SDK.Internal.ServerTimingTest                     as ServerTimingTest+import qualified Instana.SDK.Internal.SpanStackTest                        as SpanStackTest+import qualified Instana.SDK.Internal.W3CTraceContextTest                  as W3CTraceContextTest+import qualified Instana.SDK.SpanDataTest                                  as SpanDataTest+import qualified Instana.SDK.SpanTest                                      as SpanTest+import qualified Instana.SDK.TracingHeadersTest                            as TracingHeadersTest  import           Test.HUnit @@ -27,6 +28,7 @@ allTests =   TestList     [ ConfigTest.allTests+    , DefaultGatewayIpTest.allTests     , IdTest.allTests     , LoggingTest.allTests     , MetricsCompressionTest.allTests@@ -34,9 +36,9 @@     , SchedFileTest.allTests     , SecretsTest.allTests     , ServerTimingTest.allTests+    , SpanDataTest.allTests     , SpanStackTest.allTests     , SpanTest.allTests-    , SpanDataTest.allTests     , TracingHeadersTest.allTests     , W3CTraceContextTest.allTests     ]