Created
July 23, 2010 14:03
-
-
Save robertpi/487474 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module LP | |
open System | |
open System.IO | |
open System.Text.RegularExpressions | |
/// Opens the given file and returns a sequence of it's lines. This sequence is lazy, as lines are consumed they | |
/// will be read from the disk. This is useful for large files as it provides a convient way to read them without | |
/// pulling them all into memory | |
let readAllLinesLazy file = | |
seq { use textReader = new StreamReader(File.Open(file, FileMode.Open, FileAccess.Read)) | |
let header = textReader.ReadLine() | |
while not textReader.EndOfStream do | |
yield textReader.ReadLine() } | |
/// Sorts the files in the given directory, starting with the oldest, a returns a sequence of thier lines. Similarly | |
/// to "readAllLinesLazy" this sequence is lazy so we never drag the whole collection into memory at once | |
let allLinesOfDir dir = | |
seq { let files = Directory.GetFiles dir | |
let sortedInfos = | |
files | |
|> Seq.map (fun x -> new FileInfo(x)) | |
|> Seq.sortBy (fun x -> x.LastWriteTime) | |
for file in sortedInfos do yield! readAllLinesLazy file.FullName } | |
/// grep like function that filters the given line list, only to include those lines with contain at least one of the given lines | |
let incl orItemsToFind linesList = | |
linesList | |
|> Seq.filter (fun (x: string) -> orItemsToFind |> Seq.exists (fun text -> x.Contains(text))) | |
/// Similar to incl, except that it each line is returned in a block with the "window" number of previous lines and following lines | |
/// WARNING: will exculde lines at very beginning or end of the sequence | |
let inclWind window orItemsToFind linesList = | |
let windowTotal = (window * 2) + 1 | |
Seq.windowed windowTotal linesList | |
|> Seq.filter (fun (lines: string[]) -> orItemsToFind |> Seq.exists (fun text -> lines.[window].Contains(text))) | |
|> Seq.map (fun (lines: string[]) -> String.Join(Environment.NewLine, lines)) | |
// filters the given line list exculding those lines that contain a at least one of the given substrings | |
let excl orItemsToFilter linesList = | |
linesList | |
|> Seq.filter (fun (x: string) -> not (orItemsToFilter |> Seq.exists (fun text -> x.Contains(text)))) | |
// prints a list of lines | |
let print lines = Seq.iter (printfn "%s") lines | |
/// prints a sequence of lines prefixed by the thier line number | |
let printn lines = Seq.iteri (printfn "%i. %s") lines | |
/// prints a set of anything, using F#'s pretty preting | |
let printa lines= Seq.iter (printfn "%A") lines | |
/// inter-weaves the given line between each of the lines, useful for seperating big blocks | |
let interWeave line lines = | |
seq { for x in lines do | |
yield x | |
yield line } | |
/// Regex to extract our elapsed time counter (more accurate than log timestamps) | |
let elapsedRegex = new Regex("Elapsed:(?<time>\d+\.\d*)", RegexOptions.Compiled) | |
// Exctracts | |
let extractLatence line = | |
let res = elapsedRegex.Match(line) | |
if res.Success then | |
Some (float res.Groups.["time"].Value), line | |
else | |
None, line | |
let formatLatenceLine (optTime, line)= | |
let time = match optTime with Some x -> string x | None -> "\t" | |
sprintf "%s\t%s" time line | |
let getLatence lines userRef showall = | |
lines | |
|> Seq.map extractLatence | |
|> Seq.filter (fun (opt, line) -> line.Contains(userRef) && (showall || Option.isSome opt)) | |
let getLatenceFormat userRef showall lines = | |
getLatence lines userRef showall | |
|> Seq.map formatLatenceLine | |
let printl lines = lines |> Seq.map formatLatenceLine |> print | |
let date (s: string) = | |
let success, res = DateTime.TryParseExact(s, "yyyy-MM-dd HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AllowTrailingWhite ||| System.Globalization.DateTimeStyles.AllowLeadingWhite) | |
if success then res | |
else DateTime.MinValue //failwith (sprintf "ugh: %s" s) | |
let splitDateAndLine (line: string) = | |
let time = date line.[ 0 .. 22 ] | |
time, line.[ 23 .. line.Length - 1 ] | |
let getLinesByDateRange startd endd lines = | |
let isBetween (line: string) = | |
let time = date line.[0 .. 22 ] | |
startd <= time && time <= endd | |
lines | |
|> Seq.filter isBetween | |
let printLinesByDateRange startd endd lines = | |
getLinesByDateRange startd endd lines | |
let marketDataLines lineNo marketInfoLines = | |
let md: string = Seq.nth lineNo marketInfoLines | |
md.Split([|"Market spot:"|], StringSplitOptions.RemoveEmptyEntries) | |
let exceptionSearch showHeader showTrace lines = | |
Seq.windowed 50 lines | |
|> Seq.filter(fun (window: string[]) -> window.[1].Contains("Exception:")) | |
|> Seq.map(fun (window: string[]) -> | |
let stackTrace = | |
if showTrace then | |
window |> Seq.filter(fun line -> line.StartsWith(" ")) | |
else | |
[] :> seq<string> | |
let headers = | |
if showHeader then | |
window.[0 .. 1] | |
else | |
window.[1 .. 1] | |
let allLines = | |
seq { yield! headers; yield! stackTrace } | |
String.Join(Environment.NewLine, allLines |> Seq.toArray)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment