diff --git a/.github/workflows/haskell-ci.yml b/.github/workflows/haskell-ci.yml new file mode 100644 index 0000000..136d1f6 --- /dev/null +++ b/.github/workflows/haskell-ci.yml @@ -0,0 +1,248 @@ +# This GitHub workflow config has been generated by a script via +# +# haskell-ci 'github' 'ekg-core.cabal' +# +# To regenerate the script (for example after adjusting tested-with) run +# +# haskell-ci regenerate +# +# For more information, see https://github.com/haskell-CI/haskell-ci +# +# version: 0.19.20240708 +# +# REGENDATA ("0.19.20240708",["github","ekg-core.cabal"]) +# +name: Haskell-CI +on: + - push + - pull_request +jobs: + linux: + name: Haskell-CI - Linux - ${{ matrix.compiler }} + runs-on: ubuntu-20.04 + timeout-minutes: + 60 + container: + image: buildpack-deps:jammy + continue-on-error: ${{ matrix.allow-failure }} + strategy: + matrix: + include: + - compiler: ghc-9.10.1 + compilerKind: ghc + compilerVersion: 9.10.1 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.8.2 + compilerKind: ghc + compilerVersion: 9.8.2 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.6.6 + compilerKind: ghc + compilerVersion: 9.6.6 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.6.4 + compilerKind: ghc + compilerVersion: 9.6.4 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.4.8 + compilerKind: ghc + compilerVersion: 9.4.8 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.2.8 + compilerKind: ghc + compilerVersion: 9.2.8 + setup-method: ghcup + allow-failure: false + - compiler: ghc-9.0.2 + compilerKind: ghc + compilerVersion: 9.0.2 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.10.7 + compilerKind: ghc + compilerVersion: 8.10.7 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.8.3 + compilerKind: ghc + compilerVersion: 8.8.3 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.6.5 + compilerKind: ghc + compilerVersion: 8.6.5 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.4.4 + compilerKind: ghc + compilerVersion: 8.4.4 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.2.2 + compilerKind: ghc + compilerVersion: 8.2.2 + setup-method: ghcup + allow-failure: false + - compiler: ghc-8.0.2 + compilerKind: ghc + compilerVersion: 8.0.2 + setup-method: ghcup + allow-failure: false + fail-fast: false + steps: + - name: apt + run: | + apt-get update + apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5 libnuma-dev + mkdir -p "$HOME/.ghcup/bin" + curl -sL https://downloads.haskell.org/ghcup/0.1.30.0/x86_64-linux-ghcup-0.1.30.0 > "$HOME/.ghcup/bin/ghcup" + chmod a+x "$HOME/.ghcup/bin/ghcup" + "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false) + "$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false) + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: Set PATH and environment variables + run: | + echo "$HOME/.cabal/bin" >> $GITHUB_PATH + echo "LANG=C.UTF-8" >> "$GITHUB_ENV" + echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV" + echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV" + HCDIR=/opt/$HCKIND/$HCVER + HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER") + HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#') + HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#') + echo "HC=$HC" >> "$GITHUB_ENV" + echo "HCPKG=$HCPKG" >> "$GITHUB_ENV" + echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV" + echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV" + HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))') + echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV" + echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV" + echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV" + echo "HEADHACKAGE=false" >> "$GITHUB_ENV" + echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV" + echo "GHCJSARITH=0" >> "$GITHUB_ENV" + env: + HCKIND: ${{ matrix.compilerKind }} + HCNAME: ${{ matrix.compiler }} + HCVER: ${{ matrix.compilerVersion }} + - name: env + run: | + env + - name: write cabal config + run: | + mkdir -p $CABAL_DIR + cat >> $CABAL_CONFIG <> $CABAL_CONFIG < cabal-plan.xz + echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2 cabal-plan.xz' | sha256sum -c - + xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan + rm -f cabal-plan.xz + chmod a+x $HOME/.cabal/bin/cabal-plan + cabal-plan --version + - name: checkout + uses: actions/checkout@v4 + with: + path: source + - name: initial cabal.project for sdist + run: | + touch cabal.project + echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project + cat cabal.project + - name: sdist + run: | + mkdir -p sdist + $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist + - name: unpack + run: | + mkdir -p unpacked + find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \; + - name: generate cabal.project + run: | + PKGDIR_ekg_core="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/ekg-core-[0-9.]*')" + echo "PKGDIR_ekg_core=${PKGDIR_ekg_core}" >> "$GITHUB_ENV" + rm -f cabal.project cabal.project.local + touch cabal.project + touch cabal.project.local + echo "packages: ${PKGDIR_ekg_core}" >> cabal.project + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo "package ekg-core" >> cabal.project ; fi + if [ $((HCNUMVER >= 80200)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi + cat >> cabal.project <> cabal.project.local + cat cabal.project + cat cabal.project.local + - name: dump install plan + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all + cabal-plan + - name: restore cache + uses: actions/cache/restore@v4 + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store + restore-keys: ${{ runner.os }}-${{ matrix.compiler }}- + - name: install dependencies + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all + - name: build w/o tests + run: | + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: build + run: | + $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always + - name: cabal check + run: | + cd ${PKGDIR_ekg_core} || false + ${CABAL} -vnormal check + - name: haddock + run: | + $CABAL v2-haddock --disable-documentation --haddock-all $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all + - name: unconstrained build + run: | + rm -f cabal.project.local + $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all + - name: save cache + uses: actions/cache/save@v4 + if: always() + with: + key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }} + path: ~/.cabal/store diff --git a/.gitignore b/.gitignore index 12b9885..a014a4b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ cabal.config cabal.sandbox.config examples/Group *.sublime-* +dist-newstyle/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 819b18b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,151 +0,0 @@ -# This Travis job script has been generated by a script via -# -# haskell-ci 'ekg-core.cabal' -# -# For more information, see https://github.com/haskell-CI/haskell-ci -# -# version: 0.3.20190429 -# -language: c -dist: xenial -git: - # whether to recursively clone submodules - submodules: false -cache: - directories: - - $HOME/.cabal/packages - - $HOME/.cabal/store -before_cache: - - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log - # remove files that are regenerated by 'cabal update' - - rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.* - - rm -fv $CABALHOME/packages/hackage.haskell.org/*.json - - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache - - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar - - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx - - rm -rfv $CABALHOME/packages/head.hackage -matrix: - include: - - compiler: ghc-8.10.1 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.10.1","cabal-install-3.2"]}} - - compiler: ghc-8.8.3 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.3","cabal-install-3.0"]}} - - compiler: ghc-8.6.5 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-2.4"]}} - - compiler: ghc-8.4.4 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-2.4"]}} - - compiler: ghc-8.2.2 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-2.4"]}} - - compiler: ghc-8.0.2 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-2.4"]}} - - compiler: ghc-7.10.3 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-2.4"]}} - - compiler: ghc-7.8.4 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-2.4"]}} - - compiler: ghc-7.6.3 - addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.6.3","cabal-install-2.4"]}} -before_install: - - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//') - - HCPKG="$HC-pkg" - - unset CC - - CABAL=/opt/ghc/bin/cabal - - CABALHOME=$HOME/.cabal - - export PATH="$CABALHOME/bin:$PATH" - - TOP=$(pwd) - - HCNUMVER=$(( $(${HC} --numeric-version|sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 * 10000 + \2 * 100 + \3/') )) - - echo $HCNUMVER - - CABAL="$CABAL -vnormal+nowrap+markoutput" - - set -o pipefail - - | - echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }' >> .colorful.awk - echo 'BEGIN { state = "output"; }' >> .colorful.awk - echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }' >> .colorful.awk - echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }' >> .colorful.awk - echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk - echo ' if (state == "cabal") {' >> .colorful.awk - echo ' print blue($0)' >> .colorful.awk - echo ' } else {' >> .colorful.awk - echo ' print $0' >> .colorful.awk - echo ' }' >> .colorful.awk - echo '}' >> .colorful.awk - - cat .colorful.awk - - | - color_cabal_output () { - awk -f $TOP/.colorful.awk - } - - echo text | color_cabal_output -install: - - ${CABAL} --version - - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]" - - TEST=--enable-tests - - BENCH=--enable-benchmarks - - GHCHEAD=${GHCHEAD-false} - - rm -f $CABALHOME/config - - | - echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config - echo "remote-build-reporting: anonymous" >> $CABALHOME/config - echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config - echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config - echo "world-file: $CABALHOME/world" >> $CABALHOME/config - echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config - echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config - echo "installdir: $CABALHOME/bin" >> $CABALHOME/config - echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config - echo "store-dir: $CABALHOME/store" >> $CABALHOME/config - echo "install-dirs user" >> $CABALHOME/config - echo " prefix: $CABALHOME" >> $CABALHOME/config - echo "repository hackage.haskell.org" >> $CABALHOME/config - echo " url: http://hackage.haskell.org/" >> $CABALHOME/config - - cat $CABALHOME/config - - rm -fv cabal.project cabal.project.local cabal.project.freeze - - travis_retry ${CABAL} v2-update -v - # Generate cabal.project - - rm -rf cabal.project cabal.project.local cabal.project.freeze - - touch cabal.project - - | - echo 'packages: "."' >> cabal.project - - | - echo "write-ghc-environment-files: always" >> cabal.project - - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(ekg-core)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - - cat cabal.project || true - - cat cabal.project.local || true - - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi - - ${CABAL} v2-freeze -w ${HC} ${TEST} ${BENCH} | color_cabal_output - - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'" - - rm cabal.project.freeze - - ${CABAL} v2-build -w ${HC} ${TEST} ${BENCH} --dep -j2 all | color_cabal_output - - ${CABAL} v2-build -w ${HC} --disable-tests --disable-benchmarks --dep -j2 all | color_cabal_output -script: - - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX) - # Packaging... - - ${CABAL} v2-sdist all | color_cabal_output - # Unpacking... - - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/ - - cd ${DISTDIR} || false - - find . -maxdepth 1 -name '*.tar.gz' -exec tar -xvf '{}' \; - # Generate cabal.project - - rm -rf cabal.project cabal.project.local cabal.project.freeze - - touch cabal.project - - | - echo 'packages: "ekg-core-*/*.cabal"' >> cabal.project - - | - echo "write-ghc-environment-files: always" >> cabal.project - - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(ekg-core)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - - cat cabal.project || true - - cat cabal.project.local || true - # Building... - # this builds all libraries and executables (without tests/benchmarks) - - ${CABAL} v2-build -w ${HC} --disable-tests --disable-benchmarks all | color_cabal_output - # Building with tests and benchmarks... - # build & run tests, build benchmarks - - ${CABAL} v2-build -w ${HC} ${TEST} ${BENCH} all | color_cabal_output - # cabal check... - - (cd ekg-core-* && ${CABAL} -vnormal check) - # haddock... - - ${CABAL} v2-haddock -w ${HC} ${TEST} ${BENCH} all | color_cabal_output - # Building without installed constraints for packages in global-db... - - rm -f cabal.project.local - - ${CABAL} v2-build -w ${HC} --disable-tests --disable-benchmarks all | color_cabal_output - -# REGENDATA ["ekg-core.cabal"] -# EOF diff --git a/CHANGES.md b/CHANGES.md index 9c77f36..ed814e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +## 0.1.1.8 (2024-10-31) + + * Support more modern GHCs more directly, and include nonmoving gc stats. ([#53](https://github.com/haskell-github-trust/ekg-core/pull/53)) + ## 0.1.1.7 (2019-03-15) * Fix two bugs in `cbits` relating to distribution values diff --git a/README.md b/README.md index c819a52..1ef4216 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# ekg-core [![Hackage version](https://img.shields.io/hackage/v/ekg-core.svg?label=Hackage)](https://hackage.haskell.org/package/ekg-core) [![Build Status](https://secure.travis-ci.org/tibbe/ekg-core.svg?branch=master)](http://travis-ci.org/tibbe/ekg-core) +# ekg-core [![Hackage version](https://img.shields.io/hackage/v/ekg-core.svg?label=Hackage)](https://hackage.haskell.org/package/ekg-core) [![Build Status](https://github.com/haskell-github-trust/ekg-core/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/haskell-github-trust/ekg-core/actions/workflows/haskell-ci.yml) Library for tracking system metrics diff --git a/System/Metrics.hs b/System/Metrics.hs index bca8339..60e22b0 100644 --- a/System/Metrics.hs +++ b/System/Metrics.hs @@ -198,14 +198,14 @@ register :: T.Text -> IO () register name sample store = do atomicModifyIORef (storeState store) $ \ state@State{..} -> - case M.member name stateMetrics of - False -> let !state' = state { + if M.member name stateMetrics + then alreadyInUseError name + else let !state' = state { stateMetrics = M.insert name (Left sample) stateMetrics } in (state', ()) - True -> alreadyInUseError name -- | Raise an exception indicating that the metric name is already in -- use. @@ -331,16 +331,6 @@ createDistribution name store = do -- easily be added to a metrics store by calling their register -- function. -#if MIN_VERSION_base(4,10,0) --- | Convert nanoseconds to milliseconds. -nsToMs :: Int64 -> Int64 -nsToMs s = round (realToFrac s / (1000000.0 :: Double)) -#else --- | Convert seconds to milliseconds. -sToMs :: Double -> Int64 -sToMs s = round (s * 1000.0) -#endif - -- | Register a number of metrics related to garbage collector -- behavior. -- @@ -398,6 +388,10 @@ sToMs s = round (s * 1000.0) -- -- [@rts.gc.max_bytes_used@] Maximum number of live bytes seen so far -- +-- [@rts.gc.max_large_bytes_used@] Maximum number of live bytes seen so far just in large ojects +-- +-- [@rts.gc.max_compact_bytes_used@] Maximum number of live bytes seen so far just in compact regions +-- -- [@rts.gc.current_bytes_used@] Current number of live bytes -- -- [@rts.gc.current_bytes_slop@] Current number of bytes lost to slop @@ -418,9 +412,24 @@ sToMs s = round (s * 1000.0) -- the most active GC thread each GC. The ratio of -- @par_tot_bytes_copied@ divided by @par_max_bytes_copied@ approaches -- 1 for a maximally sequential run and approaches the number of --- threads (set by the RTS flag @-N@) for a maximally parallel run. +-- threads (set by the RTS flag @-N@) for a maximally parallel run. Deprecated by +-- GHC in later versions. +-- +-- [@rts.gc.par_balanced_bytes_copied@] Sum of balanced data copied by all threads in parallel GC, across all parallel GCs. +-- +-- [@rts.gc.nm.sync_cpu_ms@] The total CPU time used during the post-mark pause phase of the concurrent nonmoving GC. +-- +-- [@rts.gc.nm.sync_elapsed_ms@] The total time elapsed during the post-mark pause phase of the concurrent nonmoving GC. +-- +-- [@rts.gc.nm.sync_max_elapsed_ms@] The maximum elapsed length of any post-mark pause phase of the concurrent nonmoving GC. +-- +-- [@rts.gc.nm.cpu_ms@] The total CPU time used by the nonmoving GC. +-- +-- [@rts.gc.nm.elapsed_ms@] The total time elapsed during which there is a nonmoving GC active. +-- +-- [@rts.gc.nm.max_elapsed_ms@] The maximum time elapsed during any nonmoving GC cycle. registerGcMetrics :: Store -> IO () -registerGcMetrics store = +registerGcMetrics = registerGroup #if MIN_VERSION_base(4,10,0) (M.fromList @@ -440,6 +449,8 @@ registerGcMetrics store = , ("rts.gc.cpu_ms" , Counter . nsToMs . Stats.cpu_ns) , ("rts.gc.wall_ms" , Counter . nsToMs . Stats.elapsed_ns) , ("rts.gc.max_bytes_used" , Gauge . fromIntegral . Stats.max_live_bytes) + , ("rts.gc.max_large_bytes_used" , Gauge . fromIntegral . Stats.max_large_objects_bytes) + , ("rts.gc.max_compact_bytes_used" , Gauge . fromIntegral . Stats.max_compact_bytes) , ("rts.gc.current_bytes_used" , Gauge . fromIntegral . Stats.gcdetails_live_bytes . Stats.gc) , ("rts.gc.current_bytes_slop" , Gauge . fromIntegral . Stats.gcdetails_slop_bytes . Stats.gc) , ("rts.gc.max_bytes_slop" , Gauge . fromIntegral . Stats.max_slop_bytes) @@ -447,8 +458,23 @@ registerGcMetrics store = , ("rts.gc.par_tot_bytes_copied" , Gauge . fromIntegral . Stats.par_copied_bytes) , ("rts.gc.par_avg_bytes_copied" , Gauge . fromIntegral . Stats.par_copied_bytes) , ("rts.gc.par_max_bytes_copied" , Gauge . fromIntegral . Stats.cumulative_par_max_copied_bytes) +#if MIN_VERSION_base(4,11,0) + , ("rts.gc.par_balanced_bytes_copied", Gauge . fromIntegral . Stats.cumulative_par_balanced_copied_bytes) +#if MIN_VERSION_base(4,15,0) + , ("rts.gc.nm.sync_cpu_ms" , Counter . nsToMs . Stats.nonmoving_gc_sync_cpu_ns) + , ("rts.gc.nm.sync_elapsed_ms" , Counter . nsToMs . Stats.nonmoving_gc_sync_elapsed_ns) + , ("rts.gc.nm.sync_max_elapsed_ms" , Counter . nsToMs . Stats.nonmoving_gc_sync_max_elapsed_ns) + , ("rts.gc.nm.cpu_ms" , Counter . nsToMs . Stats.nonmoving_gc_cpu_ns) + , ("rts.gc.nm.elapsed_ms" , Counter . nsToMs . Stats.nonmoving_gc_elapsed_ns) + , ("rts.gc.nm.max_elapsed_ms" , Counter . nsToMs . Stats.nonmoving_gc_max_elapsed_ns) +# endif +# endif ]) getRTSStats + where + -- | Convert nanoseconds to milliseconds. + nsToMs :: Int64 -> Int64 + nsToMs s = round (realToFrac s / (1000000.0 :: Double)) #else (M.fromList [ ("rts.gc.bytes_allocated" , Counter . Stats.bytesAllocated) @@ -472,8 +498,11 @@ registerGcMetrics store = , ("rts.gc.par_max_bytes_copied" , Gauge . Stats.parMaxBytesCopied) ]) getGcStats + where + -- | Convert seconds to milliseconds. + sToMs :: Double -> Int64 + sToMs s = round (s * 1000.0) #endif - store #if MIN_VERSION_base(4,10,0) -- | Get RTS statistics. @@ -504,6 +533,14 @@ emptyRTSStats = Stats.RTSStats # if MIN_VERSION_base(4,12,0) , init_cpu_ns = 0 , init_elapsed_ns = 0 +# if MIN_VERSION_base(4,15,0) + , nonmoving_gc_sync_cpu_ns = 0 + , nonmoving_gc_sync_elapsed_ns = 0 + , nonmoving_gc_sync_max_elapsed_ns = 0 + , nonmoving_gc_cpu_ns = 0 + , nonmoving_gc_elapsed_ns = 0 + , nonmoving_gc_max_elapsed_ns = 0 +# endif # endif # endif , mutator_cpu_ns = 0 @@ -529,6 +566,13 @@ emptyGCDetails = Stats.GCDetails , gcdetails_par_max_copied_bytes = 0 # if MIN_VERSION_base(4,11,0) , gcdetails_par_balanced_copied_bytes = 0 +# if MIN_VERSION_base(4,15,0) + , gcdetails_nonmoving_gc_sync_cpu_ns = 0 + , gcdetails_nonmoving_gc_sync_elapsed_ns = 0 +# if MIN_VERSION_base(4,18,0) + , gcdetails_block_fragmentation_bytes = 0 +# endif +# endif # endif , gcdetails_sync_elapsed_ns = 0 , gcdetails_cpu_ns = 0 diff --git a/cabal.haskell-ci b/cabal.haskell-ci new file mode 100644 index 0000000..9b702c5 --- /dev/null +++ b/cabal.haskell-ci @@ -0,0 +1 @@ +distribution: jammy \ No newline at end of file diff --git a/ekg-core.cabal b/ekg-core.cabal index 830874e..2d581d4 100644 --- a/ekg-core.cabal +++ b/ekg-core.cabal @@ -1,22 +1,34 @@ -cabal-version: 1.18 -name: ekg-core -version: 0.1.1.7 -synopsis: Tracking of system metrics -description: - This library lets you defined and track system metrics. -homepage: https://github.com/tibbe/ekg-core -bug-reports: https://github.com/tibbe/ekg-core/issues -license: BSD3 -license-file: LICENSE -author: Johan Tibell -maintainer: Johan Tibell , - Mikhail Glushenkov -category: System -build-type: Simple -extra-source-files: CHANGES.md -tested-with: GHC == 8.10.1, GHC == 8.8.3, GHC == 8.6.5, - GHC == 8.4.4, GHC == 8.2.2, GHC == 8.0.2, - GHC == 7.10.3, GHC == 7.8.4, GHC == 7.6.3 +cabal-version: 1.18 +name: ekg-core +version: 0.1.1.8 +synopsis: Tracking of system metrics +description: This library lets you defined and track system metrics. +homepage: https://github.com/tibbe/ekg-core +bug-reports: https://github.com/tibbe/ekg-core/issues +license: BSD3 +license-file: LICENSE +author: Johan Tibell +maintainer: + Johan Tibell , + Mikhail Glushenkov + +category: System +build-type: Simple +extra-source-files: CHANGES.md +tested-with: + GHC ==8.0.2 + || ==8.2.2 + || ==8.4.4 + || ==8.6.5 + || ==8.8.3 + || ==8.10.7 + || ==9.0.2 + || ==9.2.8 + || ==9.4.8 + || ==9.6.4 + || ==9.6.6 + || ==9.8.2 + || ==9.10.1 library exposed-modules: @@ -33,41 +45,45 @@ library System.Metrics.ThreadId build-depends: - ghc-prim < 0.8, - base >= 4.6 && < 4.16, - containers >= 0.5 && < 0.7, - text < 1.3, - unordered-containers < 0.3 + base >=4.6 && <4.21 + , containers >=0.5 && <0.8 + , text <2.2 + , unordered-containers <0.3 - default-language: Haskell2010 + default-language: Haskell2010 + ghc-options: -Wall - ghc-options: -Wall if arch(i386) cc-options: -march=i686 - includes: distrib.h + + includes: distrib.h install-includes: distrib.h - include-dirs: cbits - c-sources: cbits/atomic.c cbits/distrib.c + include-dirs: cbits + c-sources: + cbits/atomic.c + cbits/distrib.c benchmark counter - main-is: Counter.hs - type: exitcode-stdio-1.0 + main-is: Counter.hs + type: exitcode-stdio-1.0 build-depends: - base, - ekg-core + base + , ekg-core + default-language: Haskell2010 - hs-source-dirs: benchmarks - ghc-options: -O2 -threaded -Wall + hs-source-dirs: benchmarks + ghc-options: -O2 -threaded -Wall benchmark distribution - main-is: Distribution.hs - type: exitcode-stdio-1.0 + main-is: Distribution.hs + type: exitcode-stdio-1.0 build-depends: - base, - ekg-core + base + , ekg-core + default-language: Haskell2010 - hs-source-dirs: benchmarks - ghc-options: -O2 -threaded -Wall + hs-source-dirs: benchmarks + ghc-options: -O2 -threaded -Wall source-repository head type: git