Skip to content

Instantly share code, notes, and snippets.

@robertpi
Created July 23, 2010 14:03
Show Gist options
  • Save robertpi/487474 to your computer and use it in GitHub Desktop.
Save robertpi/487474 to your computer and use it in GitHub Desktop.
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
|> print
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