Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 43fde91

Browse files
Andreas TriantafyllosCodiePP
authored andcommitted
Initial Integration of node-shell - iohk-monitoring. (#26)
* [#20] Added iohk-monitoring as dependence in stack.yaml. * [#20] Ease nix build. * [#20] Fix nix. * [#20] Renamed LoggingLayer contents. * [#20] Further renaming. * [#20] more functions in LoggingLayer Signed-off-by: Alexander Diemand <[email protected]> * [#20] upstream updated Signed-off-by: Alexander Diemand <[email protected]> * Fix some review points. * [#20] adapted to new code structure Signed-off-by: Alexander Diemand <[email protected]> * [#20] adhere to naming convention Signed-off-by: Alexander Diemand <[email protected]> * Fix BuildKite Nix builds. * [#20] global configuration Signed-off-by: Alexander Diemand <[email protected]>
1 parent 86cab5b commit 43fde91

File tree

11 files changed

+121
-87
lines changed

11 files changed

+121
-87
lines changed

.buildkite/pipeline.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
steps:
22
- label: 'nix build'
33
command: 'nix-build release.nix'
4+
agents:
5+
system: x86_64-linux
46
- label: 'stack rebuild'
57
env:
68
AWS_REGION: us-west-1

ARCHITECTURE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ For example, let's suppose we want to create a very simple logging/monitoring _f
2323
We see that the _feature_ requires a specific *configuration and has some global exception handling*.
2424
The specific configuration can be something really specific to logging, for example. We may need to read the default log level, whether it's info, debug, warn or something else - we need to define the level of information we want to save in the logs. For that, we require a specific configuration. That configuration is not part of the default configuration we usually parse when we start the _cardano-shell_ - when we parse the initial key configuration, we parse what *every feature requires*, not
2525
something specific for each _feature_.
26-
Then we have the _feature_ ready for usage and we can use the functions it contains. We will restrict this a bit later, but for now, let's suppose we can use all the functions in the module export.
26+
Then we have the _feature_ ready for usage and we can use the functions it contains. We will restrict this a bit later, but for now, let's suppose we can use all the functions in the module export.
2727
And so, all is well. We are done! But wait! What about the other _features_? Ok, so I lied, we are not done. We need to able to communicate with the other nodes. What do we need for that? Networking! So we need to construct the _networking feature_. And what does networking use? It uses loggging! How does that look like?
2828

2929
![networking_deps](https://user-images.githubusercontent.com/6264437/48932488-84ae8800-eefc-11e8-89ff-5c8d45dc0f46.jpg)
@@ -50,7 +50,7 @@ So let's draw some pictures here and make this a bit more clear. Let's simplify
5050

5151
![feature_layer_1](https://user-images.githubusercontent.com/6264437/48933434-89753b00-ef00-11e8-9edf-5f424caaba07.jpg)
5252

53-
When we complete the construction of this logging/monitoring _feature_, we get the initialized _layer_, which is the interface toward the _feature_. It's essentially a record of functions.
53+
When we complete the construction of this logging/monitoring _feature_, we get the initialized _layer_, which is the interface toward the _feature_. It's essentially a record of functions.
5454
Let's make this a bit more concrete. Let's say we have an extremely simple interface for _logging_ and all we want our users (developers) to use is this:
5555
```
5656
logInfo :: Text -> IO ()
@@ -87,7 +87,7 @@ I lied again. I simplified it a bit. If you take a look at the actual _layer_ ex
8787
![feature_layer_abstract_effect](https://user-images.githubusercontent.com/6264437/48934055-db1ec500-ef02-11e8-910a-a11885661bb2.jpg)
8888

8989
In the example, we suppose that the interface is abstract (the `m` type is abstract) and we later on define it to be `forall m. (MonadIO m, MonadLog m) => m`, so an _mtl style effect_ which has two constraints on it - it can log and do IO, which sounds good. But there is nothing perfect and there are trade-offs everywhere. Even in our nice little example. How?
90-
Let me show you. The abstract type is now constrained by two types - `MonadIO` and `MonadLog`.
90+
Let me show you. The abstract type is now constrained by two types - `MonadIO` and `MonadLog`.
9191

9292
![feature_layer_effect_escape_1](https://user-images.githubusercontent.com/6264437/48934364-fdfda900-ef03-11e8-8631-bcdb2f283eab.jpg)
9393

@@ -97,7 +97,7 @@ isn't that one of the reasons we use Haskell in the first place? Even worse, see
9797
![feature_layer_effect_escape_2](https://user-images.githubusercontent.com/6264437/48934561-d65b1080-ef04-11e8-808a-b83bee9a188b.jpg)
9898

9999
But that's not the worst part! The worst part is yet to come!
100-
What happens when we use _logging layer_ in our _networking feature_ function?
100+
What happens when we use _logging layer_ in our _networking feature_ function?
101101

102102
![feature_layer_effect_escape_3](https://user-images.githubusercontent.com/6264437/48934599-fdb1dd80-ef04-11e8-984b-4d2f4cc2eef2.jpg)
103103

@@ -114,9 +114,9 @@ Well, we can fix this. The price is hard-to-read type errors if you miss somethi
114114
So we can simply use `Rank2Types` extension and use a layer that has the constraints defined *per function*:
115115
```
116116
data LoggingLayer = LoggingLayer
117-
{ iolLogDebug :: forall m. (MonadIO m) => Text -> m ()
118-
, iolLogInfo :: forall m. (MonadIO m) => Text -> m ()
119-
, iolNonIo :: forall m. (MonadThrow m) => m ()
117+
{ llLogDebug :: forall m. (MonadIO m) => Text -> m ()
118+
, llLogInfo :: forall m. (MonadIO m) => Text -> m ()
119+
, llLockNonIO :: forall m. (MonadThrow m) => m ()
120120
}
121121
```
122122

app/Cardano/Shell/Features/Logging.hs

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,32 @@
44
module Cardano.Shell.Features.Logging
55
( LoggingLayer (..)
66
, createLoggingFeature
7+
, Trace
78
) where
89

9-
import Cardano.Prelude
10+
import Cardano.Prelude hiding (trace)
1011

11-
import Control.Exception.Safe (MonadThrow)
12+
import Cardano.BM.Configuration.Static (defaultConfigStdout)
13+
import Cardano.BM.Setup (setupTrace)
14+
import Cardano.BM.Trace (Trace)
15+
import qualified Cardano.BM.Trace as Trace
1216

1317
import Cardano.Shell.Types (CardanoConfiguration, CardanoEnvironment,
14-
CardanoFeature (..),
15-
CardanoFeatureInit (..),
16-
NoDependency (..))
18+
CardanoFeature (..), CardanoFeatureInit (..),
19+
NoDependency (..), ccLogConfig, ccLogPath)
1720

1821
--------------------------------------------------------------------------------
1922
-- Loggging feature
2023
--------------------------------------------------------------------------------
2124

22-
--------------------------------
23-
-- Exceptions
24-
--------------------------------
25-
26-
data LoggingException
27-
= MissingLogFileException
28-
deriving (Eq, Show)
29-
30-
instance Exception LoggingException
31-
3225
--------------------------------
3326
-- Configuration
3427
--------------------------------
3528

36-
-- Ideas picked up from https://github.com/input-output-hk/cardano-sl/blob/develop/util/src/Pos/Util/Log/LoggerConfig.hs
37-
38-
data RotationParameters = RotationParameters
39-
{ _rpLogLimitBytes :: !Word64 -- ^ max size of file in bytes
40-
, _rpMaxAgeHours :: !Word -- ^ hours
41-
, _rpKeepFilesNum :: !Word -- ^ number of files to keep
42-
} deriving (Generic, Show, Eq)
43-
44-
45-
testRotationParameters :: RotationParameters
46-
testRotationParameters = RotationParameters
47-
{ _rpLogLimitBytes = 10
48-
, _rpMaxAgeHours = 3
49-
, _rpKeepFilesNum = 5
50-
}
29+
data LoggingParameters = LoggingParameters
30+
{ configFp :: FilePath
31+
, prefixFp :: FilePath
32+
} deriving (Show, Eq)
5133

5234
--------------------------------
5335
-- Layer
@@ -60,33 +42,36 @@ testRotationParameters = RotationParameters
6042
-- the functions effects and constraining the user (programmer) of those function to use specific effects in them.
6143
-- https://github.com/input-output-hk/cardano-sl/blob/develop/util/src/Pos/Util/Log/LogSafe.hs
6244
data LoggingLayer = LoggingLayer
63-
{ iolLogDebug :: forall m. (MonadIO m) => Text -> m ()
64-
, iolLogInfo :: forall m. (MonadIO m) => Text -> m ()
65-
, iolNonIo :: forall m. (MonadThrow m) => m ()
66-
}
67-
68-
testLoggingLayer :: LoggingLayer
69-
testLoggingLayer = LoggingLayer
70-
{ iolLogDebug = liftIO . putTextLn
71-
, iolLogInfo = liftIO . putTextLn
72-
, iolNonIo = pure ()
45+
{ llStartTrace :: forall m. (MonadIO m) => Trace m
46+
, llLogDebug :: forall m. (MonadIO m) => Trace m -> Text -> m ()
47+
, llLogInfo :: forall m. (MonadIO m) => Trace m -> Text -> m ()
48+
, llLogNotice :: forall m. (MonadIO m) => Trace m -> Text -> m ()
49+
, llLogWarning :: forall m. (MonadIO m) => Trace m -> Text -> m ()
50+
, llLogError :: forall m. (MonadIO m) => Trace m -> Text -> m ()
51+
, llAppendName :: forall m. (MonadIO m) => Text -> Trace m -> m (Trace m)
7352
}
7453

7554
--------------------------------
7655
-- Feature
7756
--------------------------------
7857

79-
type LoggingCardanoFeature = CardanoFeatureInit NoDependency RotationParameters LoggingLayer
58+
type LoggingCardanoFeature = CardanoFeatureInit NoDependency LoggingParameters LoggingLayer
8059

8160
createLoggingFeature :: CardanoEnvironment -> CardanoConfiguration -> IO (LoggingLayer, CardanoFeature)
8261
createLoggingFeature cardanoEnvironment cardanoConfiguration = do
8362
-- we parse any additional configuration if there is any
8463
-- We don't know where the user wants to fetch the additional configuration from, it could be from
8564
-- the filesystem, so we give him the most flexible/powerful context, @IO@.
86-
loggingConfiguration <- pure testRotationParameters
65+
loggingConfiguration <- pure $ LoggingParameters
66+
(ccLogConfig cardanoConfiguration)
67+
(ccLogPath cardanoConfiguration)
8768

8869
-- we construct the layer
89-
loggingLayer <- (featureInit loggingCardanoFeatureInit) cardanoEnvironment NoDependency cardanoConfiguration loggingConfiguration
70+
loggingLayer <- (featureInit loggingCardanoFeatureInit)
71+
cardanoEnvironment
72+
NoDependency
73+
cardanoConfiguration
74+
loggingConfiguration
9075

9176
-- we construct the cardano feature
9277
let cardanoFeature = loggingCardanoFeature loggingCardanoFeatureInit loggingLayer
@@ -96,30 +81,32 @@ createLoggingFeature cardanoEnvironment cardanoConfiguration = do
9681

9782
loggingCardanoFeatureInit :: LoggingCardanoFeature
9883
loggingCardanoFeatureInit = CardanoFeatureInit
99-
{ featureType = "LoggingMonitoringFeature"
100-
, featureInit = featureInit'
101-
, featureCleanup = featureCleanup'
84+
{ featureType = "LoggingMonitoringFeature"
85+
, featureInit = initLogging
86+
, featureCleanup = cleanupLogging
10287
}
10388
where
104-
featureInit' :: CardanoEnvironment -> NoDependency -> CardanoConfiguration -> RotationParameters -> IO LoggingLayer
105-
featureInit' = actualLoggingFeature
106-
where
107-
actualLoggingFeature :: CardanoEnvironment -> NoDependency -> CardanoConfiguration -> RotationParameters -> IO LoggingLayer
108-
actualLoggingFeature _ _ _ _ = do
109-
--putTextLn "Starting up logging!"
110-
pure testLoggingLayer
111-
112-
featureCleanup' :: LoggingLayer -> IO ()
113-
featureCleanup' _ = pure () --putTextLn "Shutting down logging feature!" -- save a file, for example
89+
initLogging :: CardanoEnvironment -> NoDependency -> CardanoConfiguration -> LoggingParameters -> IO LoggingLayer
90+
initLogging _ _ _ _logparams = do
91+
cfg <- defaultConfigStdout -- TODO initialize from 'configFp logparams'
92+
baseTrace <- setupTrace (Right cfg) "simple"
93+
pure $ LoggingLayer
94+
{ llStartTrace = Trace.natTrace liftIO baseTrace
95+
, llLogDebug = Trace.logDebug
96+
, llLogInfo = Trace.logInfo
97+
, llLogNotice = Trace.logNotice
98+
, llLogWarning = Trace.logWarning
99+
, llLogError = Trace.logError
100+
, llAppendName = Trace.appendName
101+
}
102+
cleanupLogging :: LoggingLayer -> IO ()
103+
cleanupLogging _ = pure () -- TODO
114104

115105
loggingCardanoFeature :: LoggingCardanoFeature -> LoggingLayer -> CardanoFeature
116106
loggingCardanoFeature loggingCardanoFeature' loggingLayer = CardanoFeature
117107
{ featureName = featureType loggingCardanoFeature'
118108
, featureStart = liftIO $ do
119-
--putTextLn "Starting up loggingCardanoFeature!"
120-
void $ pure loggingLayer -- or whatever it means for YOU (a specific team)
109+
void $ pure loggingLayer
121110
, featureShutdown = liftIO $ do
122-
--putTextLn "Shutting down loggingCardanoFeature!"
123111
(featureCleanup loggingCardanoFeature') loggingLayer
124112
}
125-

app/Cardano/Shell/Features/Networking.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ data NetworkLayer = NetworkLayer
5555
testNetworkLayer :: LoggingLayer -> NetworkLayer
5656
testNetworkLayer loggingLayer = NetworkLayer
5757
{ sendToNodes = \_ -> pure "SEND"
58-
, readFromNodes = \_ -> iolNonIo loggingLayer >> pure "READ"
58+
, readFromNodes = \_ -> do
59+
let m = "READ"
60+
llLogInfo loggingLayer (llStartTrace loggingLayer) m
61+
pure m
5962
}
6063

6164
--------------------------------

cardano-shell.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ executable cardano-shell-exe
7373
, cardano-prelude
7474
-- util
7575
, safe-exceptions
76+
-- features
77+
, iohk-monitoring
7678
default-language: Haskell2010
7779
default-extensions: NoImplicitPrelude
7880
OverloadedStrings

cardano-shell.nix

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{ mkDerivation, base, cardano-prelude, concurrency, contravariant
22
, dejafu, dhall, directory, ekg-core, formatting, hspec
3-
, hspec-contrib, hunit-dejafu, QuickCheck, safe-exceptions, stdenv
4-
, text, transformers
3+
, hspec-contrib, hunit-dejafu, iohk-monitoring, QuickCheck
4+
, safe-exceptions, stdenv, text, transformers
55
}:
66
mkDerivation {
77
pname = "cardano-shell";
@@ -11,7 +11,8 @@ mkDerivation {
1111
isExecutable = true;
1212
libraryHaskellDepends = [
1313
base cardano-prelude concurrency contravariant dhall directory
14-
ekg-core formatting QuickCheck safe-exceptions text transformers
14+
ekg-core formatting iohk-monitoring QuickCheck safe-exceptions text
15+
transformers
1516
];
1617
executableHaskellDepends = [
1718
base cardano-prelude safe-exceptions

iohk-monitoring.nix

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{ mkDerivation, aeson, Cabal, array, async, auto-update, base, bytestring
2+
, clock, containers, contravariant, directory, ekg, ekg-core, fetchgit
3+
, filepath, katip, lens, mtl, process, QuickCheck, random
4+
, safe-exceptions, semigroups, stdenv, stm, tasty, tasty-hunit
5+
, tasty-quickcheck, template-haskell, text, time, time-units
6+
, transformers, unix, unordered-containers, void, yaml
7+
}:
8+
mkDerivation {
9+
pname = "iohk-monitoring";
10+
version = "0.1.0.0";
11+
src = fetchgit {
12+
url = "https://github.com/input-output-hk/iohk-monitoring-framework";
13+
sha256 = "01bm1b5qfgilwlj6ygmri6l4fydd2p2awg2z9isj8jwkglv9shga";
14+
rev = "9ab53237c579698c3bf892580a7b4df2d097e270";
15+
fetchSubmodules = false;
16+
};
17+
libraryHaskellDepends = [
18+
aeson Cabal array async auto-update base bytestring clock containers
19+
contravariant directory ekg ekg-core filepath katip lens mtl
20+
safe-exceptions stm template-haskell text time time-units
21+
transformers unix unordered-containers yaml
22+
];
23+
testHaskellDepends = [
24+
Cabal array base bytestring clock containers mtl process QuickCheck
25+
random semigroups stm tasty tasty-hunit tasty-quickcheck text time
26+
time-units transformers void
27+
];
28+
description = "logging, benchmarking and monitoring framework";
29+
license = stdenv.lib.licenses.mit;
30+
hydraPlatforms = stdenv.lib.platforms.none;
31+
}

release.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ let
55
overrides = haskellPackagesNew: haskellPackagesOld: rec {
66
cardano-prelude = haskellPackagesNew.callPackage ./cardano-prelude.nix {
77
#canonical-json = pkgs.haskell.lib.dontCheck (haskellPackagesNew.callHackage "canonical-json" "0.5.0.1" {});
8-
canonical-json = pkgs.haskell.lib.dontCheck (haskellPackagesNew.callPackage ./canonical-json.nix {});
8+
canonical-json = pkgs.haskell.lib.dontCheck (haskellPackagesNew.callPackage ./canonical-json.nix {});
99
};
10+
11+
iohk-monitoring = haskellPackagesNew.callPackage ./iohk-monitoring.nix { };
1012
cardano-shell = haskellPackagesNew.callPackage ./cardano-shell.nix { };
1113
};
1214
};

src/Cardano/Shell/Types.hs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
module Cardano.Shell.Types where
44

5-
import Cardano.Prelude
5+
import Cardano.Prelude
66

7-
import Control.Concurrent.Classy (MonadConc)
7+
import Control.Concurrent.Classy (MonadConc)
88

9-
--import qualified Katip as Katip
109
import qualified System.Metrics as Ekg
1110

1211
-- | The top level module we use to run the key functions.
@@ -20,13 +19,15 @@ data ApplicationEnvironment
2019

2120
-- | A simple function to inform us.
2221
applicationProductionMode :: ApplicationEnvironment -> Bool
23-
applicationProductionMode Production = True
24-
applicationProductionMode _ = False
22+
applicationProductionMode Production = True
23+
applicationProductionMode _ = False
2524

2625
-- | Cardano configuration
2726
data CardanoConfiguration = CardanoConfiguration
2827
{ ccLogPath :: !FilePath
2928
-- ^ The location of the log files on the filesystem.
29+
, ccLogConfig :: !FilePath
30+
-- ^ The path to the log configuration.
3031
, ccDBPath :: !FilePath
3132
-- ^ The location of the DB on the filesystem.
3233
, ccApplicationLockFile :: !FilePath
@@ -38,15 +39,14 @@ data CardanoConfiguration = CardanoConfiguration
3839
-- | The common runtime environment for all features in the server.
3940
-- All features have access to this environment.
4041
data CardanoEnvironment = CardanoEnvironment
41-
{ ceLogEnv :: Text --Katip.LogEnv
42-
, ceEkgStore :: Ekg.Store
42+
{ ceLogEnv :: Text
43+
, ceEkgStore :: Ekg.Store
4344
-- ...
4445
}
4546

4647
-- | Initalise 'ServerEnv'
4748
initializeCardanoEnvironment :: IO CardanoEnvironment
4849
initializeCardanoEnvironment = do
49-
-- logenv <- Katip.initLogEnv (...) (...)
5050
ekgStore <- Ekg.newStore
5151
return CardanoEnvironment
5252
{ ceLogEnv = "To implement"
@@ -55,7 +55,7 @@ initializeCardanoEnvironment = do
5555

5656
loadCardanoConfiguration :: IO CardanoConfiguration
5757
loadCardanoConfiguration = do
58-
pure $ CardanoConfiguration mempty mempty mempty
58+
pure $ CardanoConfiguration mempty mempty mempty mempty
5959

6060
-- | The option to not have any additional dependency for the @CardanoFeature@.
6161
data NoDependency = NoDependency
@@ -81,11 +81,11 @@ data CardanoFeatureInit dependency configuration layer = CardanoFeatureInit
8181

8282
-- | The interface for the running feature, the high-level interface we use for running it.
8383
data CardanoFeature = CardanoFeature
84-
{ featureName :: Text
84+
{ featureName :: Text
8585
-- ^ The name of the feature.
86-
, featureStart :: forall m. (MonadIO m, MonadConc m) => m ()
86+
, featureStart :: forall m. (MonadIO m, MonadConc m) => m ()
8787
-- ^ What we call when we start the feature.
88-
, featureShutdown :: forall m. (MonadIO m, MonadConc m) => m ()
88+
, featureShutdown :: forall m. (MonadIO m, MonadConc m) => m ()
8989
-- ^ What we call when we shut down the feature.
9090
}
9191

stack-shell.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let
1111

1212
pkgs = import nixpkgs { inherit config; };
1313

14-
in
14+
in
1515
with pkgs;
1616

1717
haskell.lib.buildStackProject {

0 commit comments

Comments
 (0)