diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2012, yihuang
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of yihuang nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Network/Wai/Application/Monitoring.hs b/Network/Wai/Application/Monitoring.hs
new file mode 100644
--- /dev/null
+++ b/Network/Wai/Application/Monitoring.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE RecordWildCards, OverloadedStrings #-}
+module Network.Wai.Application.Monitoring (monitorGC) where
+
+import Control.Monad.IO.Class (liftIO)
+import qualified Data.HashMap.Strict as M
+import qualified GHC.Stats as Stats
+import Network.HTTP.Types (status200)
+import Network.Wai (Application, Response(ResponseBuilder))
+import Blaze.ByteString.Builder (fromLazyByteString)
+import Data.Aeson (toJSON, Value(Object))
+import Data.Aeson.Encode (encode)
+
+monitorGC :: Application
+monitorGC _ = do
+    stats <- liftIO Stats.getGCStats
+    return $ ResponseBuilder
+                status200
+                [("Content-Type", "application/json")]
+                $ fromLazyByteString $ encode $ partitionGCStats stats
+
+partitionGCStats :: Stats.GCStats
+                 -> Value
+partitionGCStats (Stats.GCStats {..}) =
+    Object $ M.fromList [("counters", counters), ("gauges", gauges)]
+  where
+    counters = Object $ M.fromList
+        [ ("bytes_allocated"          , toJSON bytesAllocated)
+        , ("num_gcs"                  , toJSON numGcs)
+        , ("num_bytes_usage_samples"  , toJSON numByteUsageSamples)
+        , ("cumulative_bytes_used"    , toJSON cumulativeBytesUsed)
+        , ("bytes_copied"             , toJSON bytesCopied)
+        , ("mutator_cpu_seconds"      , toJSON mutatorCpuSeconds)
+        , ("mutator_wall_seconds"     , toJSON mutatorWallSeconds)
+        , ("gc_cpu_seconds"           , toJSON gcCpuSeconds)
+        , ("gc_wall_seconds"          , toJSON gcWallSeconds)
+        , ("cpu_seconds"              , toJSON cpuSeconds)
+        , ("wall_seconds"             , toJSON wallSeconds)
+        ]
+    gauges = Object $ M.fromList
+        [ ("max_bytes_used"           , toJSON maxBytesUsed)
+        , ("current_bytes_used"       , toJSON currentBytesUsed)
+        , ("current_bytes_slop"       , toJSON currentBytesSlop)
+        , ("max_bytes_slop"           , toJSON maxBytesSlop)
+        , ("peak_megabytes_allocated" , toJSON $ peakMegabytesAllocated*1024*1024)
+        , ("par_avg_bytes_copied"     , toJSON parAvgBytesCopied)
+        , ("par_max_bytes_copied"     , toJSON parMaxBytesCopied)
+        ]
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/gc-monitoring-wai.cabal b/gc-monitoring-wai.cabal
new file mode 100644
--- /dev/null
+++ b/gc-monitoring-wai.cabal
@@ -0,0 +1,61 @@
+-- gc-monitoring-wai.cabal auto-generated by cabal init. For
+-- additional options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+-- The name of the package.
+Name:                gc-monitoring-wai
+
+-- The package version. See the Haskell package versioning policy
+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
+-- standards guiding when and how versions should be incremented.
+Version:             0.1
+
+-- A short (one-line) description of the package.
+Synopsis:            a wai application to show GHC.GCStats
+description:         a wai application to show GHC.GCStats, look `test.hs` for usage, package also contains a munin plugin script in python.
+
+-- A longer description of the package.
+-- Description:         
+
+-- URL for the project homepage or repository.
+Homepage:            https://github.com/yihuang/gc-monitoring-wai
+
+-- The license under which the package is released.
+License:             BSD3
+
+-- The file containing the license text.
+License-file:        LICENSE
+
+-- The package author(s).
+Author:              yihuang
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+Maintainer:          yi.codeplayer@gmail.com
+
+-- A copyright notice.
+-- Copyright:           
+
+Category:            Web
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+Extra-source-files:  test.hs
+                     munin/ghc_gcstats
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.2
+
+
+Library
+  Exposed-modules:     Network.Wai.Application.Monitoring
+  ghc-options:         -Wall
+  Build-depends:       base >= 4.5 && < 5
+                     , transformers
+                     , unordered-containers
+                     , text
+                     , blaze-builder
+                     , http-types
+                     , wai
+                     , aeson
diff --git a/munin/ghc_gcstats b/munin/ghc_gcstats
new file mode 100644
--- /dev/null
+++ b/munin/ghc_gcstats
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+import simplejson as json
+
+sampledata = json.loads('{"counters": {"gc_wall_seconds":718.84982,"mutator_wall_seconds":18593.219972,"mutator_cpu_seconds":47.982996,"gc_cpu_seconds":708.656291,"num_bytes_usage_samples":3857,"cumulative_bytes_used":372753355456,"bytes_copied":371706782944,"bytes_allocated":44868015464,"num_gcs":86790,"cpu_seconds":756.643287,"wall_seconds":19312.069792},"gauges":{"par_max_bytes_copied":0,"current_bytes_used":104068488,"par_avg_bytes_copied":0,"peak_megabytes_allocated":302,"current_bytes_slop":0,"max_bytes_slop":1711464,"max_bytes_used":117574008}}')
+
+if __name__ == '__main__':
+    import sys
+    args = len(sys.argv)
+    if args==2 and sys.argv[1] == 'autoconf':
+        print 'yes'
+    elif args==2 and sys.argv[1] == 'config':
+        print '''\
+graph_title ghc gc stats
+graph_vlabel count
+graph_category ghc
+'''
+        for t in ['counters', 'gauges']:
+            type = t[:-1].upper()
+            for field in sampledata[t].keys():
+                print '%(field)s.label %(field)s'%locals()
+                print '%(field)s.type %(type)'%locals()
+
+        print 'graph_args --base 1000'
+    else:
+        import urllib2
+        data = json.loads(urllib2.urlopen('http://127.0.0.1:9002/stats').read())
+        for t in ['counters', 'gauges']:
+            for k,v in data[t].items():
+                print '%s.value %s'%(k, v)
diff --git a/test.hs b/test.hs
new file mode 100644
--- /dev/null
+++ b/test.hs
@@ -0,0 +1,5 @@
+import Network.Wai
+import Network.Wai.Application.Monitoring (monitorGC)
+import Network.Wai.Handler.Warp (run)
+
+main = run 3000 monitorGC
