Skip to content

Instantly share code, notes, and snippets.

@Kimserey
Last active June 24, 2016 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Kimserey/bc500501f7f738dbfb20a31e5a40a933 to your computer and use it in GitHub Desktop.
Save Kimserey/bc500501f7f738dbfb20a31e5a40a933 to your computer and use it in GitHub Desktop.
Deedle logs exploration
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Logs</title>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<script>
function makeChart(endpoint, title) {
$.getJSON('http://127.0.0.1:8083/' + endpoint, function (result) {
$('<div style="width:100%;">').highcharts({
chart: {
type: 'spline',
zoomType: 'xy'
},
title: {
text: title
},
xAxis: {
categories: result[0].counts.map(function (e) { return e.date; })
},
yAxis: {
title: {
text: "Count"
}
},
plotOptions: {
spline: {
marker: {
enabled: false
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
pointFormat: '{series.name}: {point.y}'
},
series:
result.map(function (e) {
return {
name: e.instance,
data: e.counts.map(function (e) { return e.count; })
};
})
}).appendTo('body');
});
}
makeChart('errors', 'Error per hours');
makeChart('mdrefreshes', 'MD refreshses per hours');
</script>
</body>
</html>
#I __SOURCE_DIRECTORY__
#load "../packages/Deedle/Deedle.fsx"
open Deedle
open System
open System.IO
Environment.CurrentDirectory <- __SOURCE_DIRECTORY__
let csvPath = "../data"
type Log = {
Date: DateTime
Level: string
Source: string
Text: string
Instance: string
}
let df =
Directory.GetFiles(csvPath, "*.csv")
|> Seq.map (fun (path: string) -> Frame.ReadCsv(path, hasHeaders = false))
|> Seq.map (fun df -> df |> Frame.indexColsWith [ "Sequence"; "Date"; "Level"; "ThreadId"; "Source"; "Text"; "Exception"; "Instance" ])
|> Seq.collect (fun df -> df |> Frame.rows |> Series.observations)
|> Seq.map snd
|> Seq.filter (fun s -> s.TryGetAs<DateTime>("Date").HasValue)
|> Seq.map (fun s ->
{ Date = s.GetAs<DateTime>("Date")
Level = s.GetAs<string>("Level")
Source = s.GetAs<string>("Source")
Text = s.GetAs<string>("Text")
Instance = s.GetAs<string>("Instance") })
|> Frame.ofRecords
type Data = {
Instance: string
Counts: Count list
}
and Count = {
Date: DateTime
Count: int
}
let errors =
df
|> Frame.pivotTable
(fun _ c ->
let date = c.GetAs<DateTime>("Date")
new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0))
(fun _ c -> c.GetAs<string>("Instance"))
(fun f ->
f
|> Frame.filterRowValues (fun c -> c.GetAs<string>("Level") = "error")
|> Frame.getCols
|> Stats.count)
|> Frame.fillMissingWith 0
|> Frame.sortRowsByKey
|> Frame.getCols
|> Series.observations
|> Seq.map (fun (k, v) ->
{ Instance = k
Counts =
v
|> Series.observations
|> Seq.map (fun (k, v) ->
{ Date = k
Count = v })
|> Seq.toList })
|> Seq.toList
let mdRefreshes =
df
|> Frame.pivotTable
(fun _ c ->
let date = c.GetAs<DateTime>("Date")
new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0))
(fun _ c -> c.GetAs<string>("Instance"))
(fun f ->
f
|> Frame.filterRowValues (fun c -> c.GetAs<string>("Text").Contains("md-refresh"))
|> Frame.getCols
|> Stats.count)
|> Frame.fillMissingWith 0
|> Frame.sortRowsByKey
|> Frame.getCols
|> Series.observations
|> Seq.map (fun (k, v) ->
{ Instance = k
Counts =
v
|> Series.observations
|> Seq.map (fun (k, v) ->
{ Date = k
Count = v })
|> Seq.toList })
|> Seq.toList
#I __SOURCE_DIRECTORY__
#r "../packages/Suave/lib/net40/Suave.dll"
#r "../packages/Newtonsoft.Json/lib/net40/Newtonsoft.Json.dll"
open Suave
open Suave.Json
open Suave.Filters
open Suave.Operators
open Suave.Successful
open Suave.Writers
open Newtonsoft.Json
open Newtonsoft.Json.Serialization
let JSON v =
OK (JsonConvert.SerializeObject(v, new JsonSerializerSettings(ContractResolver = new CamelCasePropertyNamesContractResolver())))
>=> setMimeType "application/json; charset=utf-8"
>=> setHeader "Access-Control-Allow-Origin" "*"
>=> setHeader "Access-Control-Allow-Headers" "content-type"
let app =
GET >=> choose
[ path "/errors" >=> JSON errors
path "/mdrefreshes" >=> JSON mdRefreshes ]
startWebServer defaultConfig app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment