Private/SampleJson.ps1
|
#Requires -Version 5.1 function Initialize-SMBeatSampleJsonNative { if ($script:SMBeatSampleJsonReady) { return $true } if ($script:SMBeatSampleJsonFailed) { return $false } if ('SMBeat.Native.SampleAggregator' -as [type]) { $script:SMBeatSampleJsonReady = $true return $true } if ('SMBeat.Native.SampleJson' -as [type]) { $script:SMBeatSampleJsonFailed = $true return $false } $code = @' using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; using System.Collections; namespace SMBeat.Native { public sealed class SampleRecord { public string ts { get; set; } public DateTime TsUtc { get; set; } public string server { get; set; } public string kind { get; set; } public string name { get; set; } public string client { get; set; } public string user { get; set; } public long readBytesDelta { get; set; } public long writeBytesDelta { get; set; } public long sentBytesDelta { get; set; } public long receivedBytesDelta { get; set; } public int sampleIntervalSec { get; set; } } public sealed class SampleWindowPair { public List<SampleRecord> Previous = new List<SampleRecord>(); public List<SampleRecord> Current = new List<SampleRecord>(); } public static class SampleJson { public static SampleRecord ParseLine(string line) { if (string.IsNullOrWhiteSpace(line)) { return null; } int i = 0; SkipWs(line, ref i); if (i >= line.Length || line[i] != '{') { return null; } i++; SampleRecord rec = new SampleRecord(); StringBuilder sb = new StringBuilder(64); bool any = false; while (i < line.Length) { SkipWs(line, ref i); if (i >= line.Length) { return null; } if (line[i] == '}') { break; } if (line[i] == ',') { i++; continue; } if (line[i] != '"') { return null; } string key; if (!TryReadString(line, ref i, sb, out key)) { return null; } SkipWs(line, ref i); if (i >= line.Length || line[i] != ':') { return null; } i++; SkipWs(line, ref i); if (i >= line.Length) { return null; } if (line[i] == '"') { string text; if (!TryReadString(line, ref i, sb, out text)) { return null; } AssignString(rec, key, text); any = true; } else if (line[i] == 'n' || line[i] == 'N') { if (!TrySkipLiteral(line, ref i, "null")) { return null; } AssignString(rec, key, null); any = true; } else if (line[i] == 't' || line[i] == 'T' || line[i] == 'f' || line[i] == 'F') { if (!TrySkipBool(line, ref i)) { return null; } } else { long n; if (!TryReadInt64(line, ref i, out n)) { return null; } AssignNumber(rec, key, n); any = true; } } if (!any || string.IsNullOrEmpty(rec.ts)) { return null; } DateTime ts; if (!TryParseTs(rec.ts, out ts)) { return null; } rec.TsUtc = ts; return rec; } private static IEnumerable<string> ReadLinesShared(string path) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (StreamReader sr = new StreamReader(fs, Encoding.UTF8, true)) { string line; while ((line = sr.ReadLine()) != null) { yield return line; } } } public static List<SampleRecord> ReadFile(string path, DateTime startUtc, DateTime endUtc) { List<SampleRecord> list = new List<SampleRecord>(); if (string.IsNullOrEmpty(path) || !File.Exists(path)) { return list; } foreach (string line in ReadLinesShared(path)) { SampleRecord rec = ParseLine(line); if (rec == null) { continue; } if (rec.TsUtc >= startUtc && rec.TsUtc < endUtc) { list.Add(rec); } } return list; } public static SampleWindowPair ReadDirectory( string dir, DateTime prevStart, DateTime prevEnd, DateTime windowStart, DateTime windowEnd) { SampleWindowPair pair = new SampleWindowPair(); if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return pair; } DateTime spanStart = prevStart < windowStart ? prevStart : windowStart; DateTime spanEnd = prevEnd > windowEnd ? prevEnd : windowEnd; DateTime startDay = spanStart.Date.AddDays(-1); DateTime endDay = spanEnd.Date.AddDays(1); string[] files = Directory.GetFiles(dir, "*.jsonl"); Array.Sort(files, StringComparer.OrdinalIgnoreCase); foreach (string path in files) { string dayPart = Path.GetFileNameWithoutExtension(path); DateTime fileDay; if (!DateTime.TryParseExact(dayPart, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out fileDay)) { continue; } if (fileDay < startDay || fileDay > endDay) { continue; } foreach (string line in ReadLinesShared(path)) { SampleRecord rec = ParseLine(line); if (rec == null) { continue; } if (rec.TsUtc >= prevStart && rec.TsUtc < prevEnd) { pair.Previous.Add(rec); } if (rec.TsUtc >= windowStart && rec.TsUtc < windowEnd) { pair.Current.Add(rec); } } } return pair; } private static void AssignString(SampleRecord rec, string key, string value) { if (key == "ts") { rec.ts = value; } else if (key == "server") { rec.server = value; } else if (key == "kind") { rec.kind = value; } else if (key == "name") { rec.name = value; } else if (key == "client") { rec.client = value; } else if (key == "user") { rec.user = value; } } private static void AssignNumber(SampleRecord rec, string key, long value) { if (key == "readBytesDelta") { rec.readBytesDelta = value; } else if (key == "writeBytesDelta") { rec.writeBytesDelta = value; } else if (key == "sentBytesDelta") { rec.sentBytesDelta = value; } else if (key == "receivedBytesDelta") { rec.receivedBytesDelta = value; } else if (key == "sampleIntervalSec") { rec.sampleIntervalSec = (int)value; } } private static bool TryParseTs(string value, out DateTime ts) { if (DateTime.TryParseExact(value, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out ts)) { return true; } return DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out ts); } private static void SkipWs(string s, ref int i) { while (i < s.Length && char.IsWhiteSpace(s[i])) { i++; } } private static bool TrySkipLiteral(string s, ref int i, string lit) { if (i + lit.Length > s.Length) { return false; } for (int k = 0; k < lit.Length; k++) { if (char.ToLowerInvariant(s[i + k]) != lit[k]) { return false; } } i += lit.Length; return true; } private static bool TrySkipBool(string s, ref int i) { if (s[i] == 't' || s[i] == 'T') { return TrySkipLiteral(s, ref i, "true"); } return TrySkipLiteral(s, ref i, "false"); } private static bool TryReadInt64(string s, ref int i, out long value) { value = 0; int start = i; if (i < s.Length && (s[i] == '-' || s[i] == '+')) { i++; } bool digit = false; while (i < s.Length && s[i] >= '0' && s[i] <= '9') { digit = true; i++; } if (i < s.Length && s[i] == '.') { i++; while (i < s.Length && s[i] >= '0' && s[i] <= '9') { i++; } } if (!digit) { return false; } string raw = s.Substring(start, i - start); double d; if (!double.TryParse(raw, NumberStyles.Float, CultureInfo.InvariantCulture, out d)) { return false; } if (d >= long.MaxValue) { value = long.MaxValue; } else if (d <= long.MinValue) { value = long.MinValue; } else { value = (long)d; } return true; } private static bool TryReadString(string s, ref int i, StringBuilder sb, out string value) { value = null; if (i >= s.Length || s[i] != '"') { return false; } i++; sb.Length = 0; while (i < s.Length) { char c = s[i]; if (c == '"') { i++; value = sb.ToString(); return true; } if (c == '\\') { i++; if (i >= s.Length) { return false; } char e = s[i]; if (e == '"' || e == '\\' || e == '/') { sb.Append(e); } else if (e == 'b') { sb.Append('\b'); } else if (e == 'f') { sb.Append('\f'); } else if (e == 'n') { sb.Append('\n'); } else if (e == 'r') { sb.Append('\r'); } else if (e == 't') { sb.Append('\t'); } else if (e == 'u' && i + 4 < s.Length) { int hex; if (!int.TryParse(s.Substring(i + 1, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hex)) { return false; } sb.Append((char)hex); i += 4; } else { sb.Append(e); } i++; continue; } sb.Append(c); i++; } return false; } } public sealed class NamedAcc { public string Name; public long Read; public long Write; public long Sent; public long Received; } public sealed class SeriesRow { public string Granularity; public DateTime PeriodStart; public DateTime PeriodEnd; public long ReadBytes; public long WriteBytes; public long SentBytes; public long ReceivedBytes; public long NicBytesIn; public long NicBytesOut; public long RetrievedBytes; public long WrittenBytes; } public sealed class AggregateResult { public long ReadBytes; public long WriteBytes; public long SentBytes; public long ReceivedBytes; public long NicBytesIn; public long NicBytesOut; public long RetrievedBytes; public long WrittenBytes; public long SmbPerfSentBytes; public long SmbPerfReceivedBytes; public int ListenCount; public int ServerKindCount; public bool WarnNicOut; public bool WarnEstataRead; public bool WarnShareLow; public bool WarnEtwWritten; public List<NamedAcc> ByServer = new List<NamedAcc>(); public List<NamedAcc> ByShare = new List<NamedAcc>(); public List<NamedAcc> ByClient = new List<NamedAcc>(); public List<NamedAcc> ByUser = new List<NamedAcc>(); public List<NamedAcc> BySmbPerf = new List<NamedAcc>(); public List<SeriesRow> Hourly = new List<SeriesRow>(); public List<SeriesRow> Daily = new List<SeriesRow>(); public List<SeriesRow> Weekly = new List<SeriesRow>(); public List<SeriesRow> HourlyForPeak = new List<SeriesRow>(); } public static class SampleAggregator { private sealed class Acc { public long Read; public long Write; public long Sent; public long Received; public void Add(long r, long w, long s, long v) { Read += r; Write += w; Sent += s; Received += v; } } private sealed class SeriesBucket { public DateTime Start; public long Read; public long Write; public long Sent; public long Received; public long ServerRead; public long ServerWrite; public long ServerSent; public long ServerRecv; public bool HasShare; public long NicIn; public long NicOut; public long Tcp445Sent; public long Tcp445Recv; public bool HasTcp445; } public static AggregateResult Run( SampleRecord[] records, DateTime startUtc, DateTime endUtc, string timeZoneId, string[] granularity, int intervalSec, bool totalsOnly) { AggregateResult result = new AggregateResult(); if (records == null) { records = new SampleRecord[0]; } if (granularity == null) { granularity = new string[0]; } TimeZoneInfo tz = ResolveTimeZone(timeZoneId); Dictionary<string, Acc> byServerFromServer = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byServerFromShares = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byServerFromUsers = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byServerFromTcp = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byShare = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byClient = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byClientTcp = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byClientEtw = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> byUser = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); Dictionary<string, Acc> bySmbPerf = new Dictionary<string, Acc>(StringComparer.OrdinalIgnoreCase); long serverRead = 0; long serverWrite = 0; long serverSent = 0; long serverRecv = 0; long shareRead = 0; long shareWrite = 0; long shareSent = 0; long shareRecv = 0; long nicIn = 0; long nicOut = 0; long smbPerfServerSent = 0; long smbPerfServerRecv = 0; long smbPerfShareSent = 0; long smbPerfShareRecv = 0; bool hasSmbServer = false; long tcp445Sent = 0; long tcp445Recv = 0; bool hasTcp445 = false; int listenCount = 0; int serverKindCount = 0; bool wantHour = !totalsOnly; bool wantDay = !totalsOnly && Wants(granularity, "Day"); bool wantWeek = !totalsOnly && Wants(granularity, "Week"); SortedDictionary<DateTime, SeriesBucket> hourMap = new SortedDictionary<DateTime, SeriesBucket>(); SortedDictionary<DateTime, SeriesBucket> dayMap = new SortedDictionary<DateTime, SeriesBucket>(); SortedDictionary<DateTime, SeriesBucket> weekMap = new SortedDictionary<DateTime, SeriesBucket>(); for (int i = 0; i < records.Length; i++) { SampleRecord rec = records[i]; if (rec == null) { continue; } long r = rec.readBytesDelta; long w = rec.writeBytesDelta; long s = rec.sentBytesDelta; long v = rec.receivedBytesDelta; string kind = rec.kind != null ? rec.kind : ""; string serverName = rec.server != null ? rec.server : ""; if (kind == "server") { serverKindCount++; serverRead += r; serverWrite += w; serverSent += s; serverRecv += v; AddAcc(byServerFromServer, serverName, r, w, s, v); } else if (kind == "share") { shareRead += r; shareWrite += w; shareSent += s; shareRecv += v; string shareName = rec.name != null ? rec.name : ""; AddAcc(byShare, shareName, r, w, s, v); AddAcc(byServerFromShares, serverName, r, w, s, v); } else if (kind == "session") { string clientKey = rec.client; if (string.IsNullOrWhiteSpace(clientKey)) { clientKey = rec.name; } string userKey = rec.user; if (string.IsNullOrWhiteSpace(userKey)) { userKey = "(unknown)"; } if (!string.IsNullOrWhiteSpace(clientKey)) { AddAcc(byClient, clientKey, r, w, s, v); } AddAcc(byUser, userKey, r, w, s, v); } else if (kind == "client") { string clientKey = rec.client; if (string.IsNullOrWhiteSpace(clientKey)) { clientKey = rec.name; } if (!string.IsNullOrWhiteSpace(clientKey)) { AddAcc(byClientEtw, clientKey, r, w, s, v); } } else if (kind == "user") { string userKey = rec.user; if (string.IsNullOrWhiteSpace(userKey)) { userKey = rec.name; } if (string.IsNullOrWhiteSpace(userKey)) { userKey = "(unknown)"; } AddAcc(byUser, userKey, r, w, s, v); if (!string.IsNullOrWhiteSpace(serverName)) { AddAcc(byServerFromUsers, serverName, r, w, s, v); } } else if (kind == "tcp445") { hasTcp445 = true; string name = rec.name != null ? rec.name : ""; if (name == "_listen445") { listenCount++; tcp445Sent += s; tcp445Recv += v; AddAcc(byServerFromTcp, serverName, 0, 0, s, v); } else { string clientKey = rec.client; if (string.IsNullOrWhiteSpace(clientKey)) { clientKey = name; } AddAcc(byClientTcp, clientKey, 0, 0, s, v); } } else if (kind == "nic") { nicIn += v; nicOut += s; } else if (kind == "smbperf") { string smbName = rec.name != null ? rec.name : ""; if (smbName == "_server") { hasSmbServer = true; smbPerfServerSent += s; smbPerfServerRecv += v; } else { AddAcc(bySmbPerf, smbName, r, w, s, v); smbPerfShareSent += s; smbPerfShareRecv += v; } } if (wantHour || wantDay || wantWeek) { DateTime local = ToLocal(rec.TsUtc, tz); if (wantHour) { AddSeriesDelta(GetBucket(hourMap, BucketStart(local, "Hour")), rec); } if (wantDay) { AddSeriesDelta(GetBucket(dayMap, BucketStart(local, "Day")), rec); } if (wantWeek) { AddSeriesDelta(GetBucket(weekMap, BucketStart(local, "Week")), rec); } } } bool useShareTotals = (shareSent + shareRecv) > (serverSent + serverRecv); long read = serverRead; long write = serverWrite; long sent = serverSent; long recv = serverRecv; Dictionary<string, Acc> byServer = byServerFromServer; if (useShareTotals) { read = shareRead; write = shareWrite; sent = shareSent; recv = shareRecv; byServer = byServerFromShares; } if (hasTcp445) { byServer = byServerFromTcp; if (byClientTcp.Count > 0) { byClient = byClientTcp; } } if (byClientEtw.Count > 0) { if (byClient.Count == 0) { byClient = byClientEtw; } else { foreach (KeyValuePair<string, Acc> ekv in byClientEtw) { Acc etw = ekv.Value; Acc cur; if (!byClient.TryGetValue(ekv.Key, out cur)) { byClient[ekv.Key] = etw; continue; } if (etw.Sent > 1048576 && cur.Sent > (long)((double)etw.Sent * 1.1)) { cur.Sent = etw.Sent; } else if (etw.Sent > cur.Sent) { cur.Sent = etw.Sent; } if (etw.Received > cur.Received) { cur.Received = etw.Received; } if (etw.Read > cur.Read) { cur.Read = etw.Read; } if (etw.Write > cur.Write) { cur.Write = etw.Write; } } } } long retrieved = nicOut; long written = recv; if (hasTcp445) { retrieved = tcp445Sent; written = tcp445Recv; } else if (nicOut > 104857600 && nicOut > (10 * Math.Max(sent, 1L))) { result.WarnNicOut = true; } long etwRetrieved = EtwRetrieved(byUser, shareSent); long etwWritten = shareRecv; foreach (KeyValuePair<string, Acc> ukv in byUser) { if (ukv.Value.Received > etwWritten) { etwWritten = ukv.Value.Received; } } bool retrievedFromEtw = false; if (hasTcp445 && nicOut > 1048576 && retrieved > nicOut && retrieved > (long)((double)nicOut * 1.1)) { if (etwRetrieved > 1048576 && VolumeNear(etwRetrieved, nicOut)) { retrieved = etwRetrieved; retrievedFromEtw = true; result.WarnEstataRead = true; } } if (hasTcp445 && retrieved > 10485760) { long shareFloor = (long)Math.Floor(retrieved * 0.1); if (shareSent < shareFloor) { result.WarnShareLow = true; } } if (hasTcp445 && etwWritten > 1048576 && etwWritten > (10 * Math.Max(written, 1L))) { written = etwWritten; result.WarnEtwWritten = true; } List<string> serverKeys = new List<string>(byServer.Keys); for (int si = 0; si < serverKeys.Count; si++) { string sk = serverKeys[si]; long etwRecv = 0; long etwSent = 0; Acc shareAcc; if (byServerFromShares.TryGetValue(sk, out shareAcc)) { etwRecv = shareAcc.Received; etwSent = shareAcc.Sent; } Acc userAcc; if (byServerFromUsers.TryGetValue(sk, out userAcc)) { if (userAcc.Received > etwRecv) { etwRecv = userAcc.Received; } if (userAcc.Sent > etwSent) { etwSent = userAcc.Sent; } } Acc cur = byServer[sk]; if (etwRecv > 1048576 && etwRecv > (10 * Math.Max(cur.Received, 1L))) { cur.Received = etwRecv; } if (retrievedFromEtw && etwSent > 1048576) { cur.Sent = etwSent; } else if (etwSent > 1048576 && cur.Sent > (long)((double)etwSent * 1.1) && nicOut > 1048576 && VolumeNear(etwSent, nicOut)) { cur.Sent = etwSent; } } if (hasTcp445 && byServer.Count == 1) { foreach (KeyValuePair<string, Acc> skv in byServer) { skv.Value.Sent = retrieved; skv.Value.Received = written; } } result.ReadBytes = read; result.WriteBytes = write; result.SentBytes = sent; result.ReceivedBytes = recv; result.NicBytesIn = nicIn; result.NicBytesOut = nicOut; result.RetrievedBytes = retrieved; result.WrittenBytes = written; result.SmbPerfSentBytes = smbPerfShareSent; result.SmbPerfReceivedBytes = smbPerfShareRecv; if (hasSmbServer && (smbPerfServerSent + smbPerfServerRecv) >= (smbPerfShareSent + smbPerfShareRecv)) { result.SmbPerfSentBytes = smbPerfServerSent; result.SmbPerfReceivedBytes = smbPerfServerRecv; } result.BySmbPerf = ToNamedList(bySmbPerf); result.ListenCount = listenCount; result.ServerKindCount = serverKindCount; result.ByServer = ToNamedList(byServer); result.ByShare = ToNamedList(byShare); result.ByClient = ToNamedList(byClient); result.ByUser = ToNamedList(byUser); if (!totalsOnly) { List<SeriesRow> hourRows = ToSeriesRows(hourMap, "Hour"); result.HourlyForPeak = hourRows; if (Wants(granularity, "Hour")) { result.Hourly = hourRows; } if (wantDay) { result.Daily = ToSeriesRows(dayMap, "Day"); } if (wantWeek) { result.Weekly = ToSeriesRows(weekMap, "Week"); } } return result; } private static TimeZoneInfo ResolveTimeZone(string timeZoneId) { if (string.IsNullOrEmpty(timeZoneId)) { return TimeZoneInfo.Utc; } try { return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); } catch (TimeZoneNotFoundException) { return TimeZoneInfo.Utc; } catch (InvalidTimeZoneException) { return TimeZoneInfo.Utc; } } private static DateTime ToLocal(DateTime utc, TimeZoneInfo tz) { DateTime asUtc = utc; if (asUtc.Kind == DateTimeKind.Local) { asUtc = asUtc.ToUniversalTime(); } else { asUtc = DateTime.SpecifyKind(asUtc, DateTimeKind.Utc); } return TimeZoneInfo.ConvertTimeFromUtc(asUtc, tz); } private static DateTime BucketStart(DateTime local, string gran) { DateTimeKind kind = local.Kind; if (gran == "Hour") { return new DateTime(local.Year, local.Month, local.Day, local.Hour, 0, 0, kind); } if (gran == "Day") { return new DateTime(local.Year, local.Month, local.Day, 0, 0, 0, kind); } DateTime date = new DateTime(local.Year, local.Month, local.Day, 0, 0, 0, kind); int offset = ((int)date.DayOfWeek + 6) % 7; return date.AddDays(-offset); } private static DateTime BucketEnd(DateTime start, string gran) { if (gran == "Hour") { return start.AddHours(1); } if (gran == "Day") { return start.AddDays(1); } return start.AddDays(7); } private static bool Wants(string[] granularity, string name) { if (granularity == null) { return false; } for (int i = 0; i < granularity.Length; i++) { if (granularity[i] == name) { return true; } } return false; } private static void AddAcc(Dictionary<string, Acc> map, string key, long r, long w, long s, long v) { if (key == null) { key = ""; } Acc acc; if (!map.TryGetValue(key, out acc)) { acc = new Acc(); map[key] = acc; } acc.Add(r, w, s, v); } private static bool VolumeNear(long left, long right) { long hi = left > right ? left : right; long lo = left < right ? left : right; if (hi <= 0) { return true; } return ((double)lo / (double)hi) >= 0.8; } private static long EtwRetrieved(Dictionary<string, Acc> byUser, long shareSent) { long userSent = 0; foreach (KeyValuePair<string, Acc> kv in byUser) { userSent += kv.Value.Sent; } if (userSent > shareSent) { return userSent; } return shareSent; } private static SeriesBucket GetBucket(SortedDictionary<DateTime, SeriesBucket> map, DateTime start) { SeriesBucket b; if (!map.TryGetValue(start, out b)) { b = new SeriesBucket(); b.Start = start; map[start] = b; } return b; } private static void AddSeriesDelta(SeriesBucket bucket, SampleRecord rec) { string kind = rec.kind != null ? rec.kind : ""; if (kind == "server") { bucket.ServerRead += rec.readBytesDelta; bucket.ServerWrite += rec.writeBytesDelta; bucket.ServerSent += rec.sentBytesDelta; bucket.ServerRecv += rec.receivedBytesDelta; } else if (kind == "share") { bucket.Read += rec.readBytesDelta; bucket.Write += rec.writeBytesDelta; bucket.Sent += rec.sentBytesDelta; bucket.Received += rec.receivedBytesDelta; bucket.HasShare = true; } else if (kind == "tcp445") { string name = rec.name != null ? rec.name : ""; if (name == "_listen445") { bucket.Tcp445Sent += rec.sentBytesDelta; bucket.Tcp445Recv += rec.receivedBytesDelta; bucket.HasTcp445 = true; } } else if (kind == "nic") { bucket.NicIn += rec.receivedBytesDelta; bucket.NicOut += rec.sentBytesDelta; } } private static List<SeriesRow> ToSeriesRows(SortedDictionary<DateTime, SeriesBucket> buckets, string granularity) { List<SeriesRow> result = new List<SeriesRow>(buckets.Count); foreach (KeyValuePair<DateTime, SeriesBucket> kv in buckets) { SeriesBucket b = kv.Value; bool useShare = b.HasShare; long readB = b.ServerRead; long writeB = b.ServerWrite; long sentB = b.ServerSent; long recvB = b.ServerRecv; if (useShare) { readB = b.Read; writeB = b.Write; sentB = b.Sent; recvB = b.Received; } long retrievedB = b.NicOut; long writtenB = recvB; if (b.HasTcp445) { retrievedB = b.Tcp445Sent; writtenB = b.Tcp445Recv; if (b.HasShare && b.Received > writtenB && b.Received > (10 * Math.Max(writtenB, 1L))) { writtenB = b.Received; } if (b.NicOut > 1048576 && b.Tcp445Sent > b.NicOut && b.Tcp445Sent > (long)((double)b.NicOut * 1.1)) { long etwRead = 0; if (b.HasShare) { etwRead = b.Sent; } if (etwRead > 1048576 && VolumeNear(etwRead, b.NicOut)) { retrievedB = etwRead; } } } SeriesRow row = new SeriesRow(); row.Granularity = granularity; row.PeriodStart = b.Start; row.PeriodEnd = BucketEnd(b.Start, granularity); row.ReadBytes = readB; row.WriteBytes = writeB; row.SentBytes = sentB; row.ReceivedBytes = recvB; row.NicBytesIn = b.NicIn; row.NicBytesOut = b.NicOut; row.RetrievedBytes = retrievedB; row.WrittenBytes = writtenB; result.Add(row); } return result; } private static List<NamedAcc> ToNamedList(Dictionary<string, Acc> map) { List<NamedAcc> list = new List<NamedAcc>(map.Count); foreach (KeyValuePair<string, Acc> kv in map) { NamedAcc n = new NamedAcc(); n.Name = kv.Key; n.Read = kv.Value.Read; n.Write = kv.Value.Write; n.Sent = kv.Value.Sent; n.Received = kv.Value.Received; list.Add(n); } list.Sort(CompareNamed); return list; } private static int CompareNamed(NamedAcc a, NamedAcc b) { long aMax = a.Sent > a.Received ? a.Sent : a.Received; long bMax = b.Sent > b.Received ? b.Sent : b.Received; return bMax.CompareTo(aMax); } } } '@ try { Add-Type -TypeDefinition $code -Language CSharp -ErrorAction Stop $script:SMBeatSampleJsonReady = $true return $true } catch { $script:SMBeatSampleJsonFailed = $true return $false } } |