Beispiel #1
0
        private static void ExportOnlyHandling(FileExportFilter fileExort, string line, bool isReceive, string dataPart, StreamWriter currentExportWriter)
        {
            string output;

            if (fileExort.ExportOnlyKey != null)
            {
                string exportOnlyValue = GetJsonSimpleStringValue(dataPart, fileExort.ExportOnlyKey);

                output = (isReceive ? "< " : "> ") + exportOnlyValue;
            }
            else
            {
                output = line;
            }

            if (fileExort.ExportWithSpaceSequence.HasValue)
            {
                var list = Enumerable
                           .Range(0, output.Length / fileExort.ExportWithSpaceSequence.Value)
                           .Select(i => output.Substring(i * fileExort.ExportWithSpaceSequence.Value, fileExort.ExportWithSpaceSequence.Value));
                output = string.Join(" ", list);
            }

            currentExportWriter.WriteLine(output);
        }
Beispiel #2
0
        public IList <StreamSession> AnalyzeDataStreamSession(string fileName, TimeSpan?roundTripTimeFilter, int?flowRateFilter, Action <int> progressPercentage, FileExportFilter fileExort, out StringBuilder errors)
        {
            this.LastFilePath = fileName;
            errors            = new StringBuilder();
            HashSet <int> ignoreSessions = new HashSet <int>();
            Dictionary <string, StreamWriter> openFileExportStreams = null;

            using (StreamReader streamReader = new StreamReader(fileName))
            {
                Dictionary <int, StreamSession> sessions = new Dictionary <int, StreamSession>();
                StreamSession currentSession             = null;

                double totalFileSize = (double)streamReader.BaseStream.Length;

                string line       = null;
                long   lineNumber = 1;
                while ((line = streamReader.ReadLine()) != null)
                {
                    string[] parts = line.Split(FieldSeparator);

                    if (parts.Length > 4)
                    {
                        // message contains \t in data part
                        // merge last parts
                        string lastPart = string.Join("", parts, 3, parts.Length - 3);
                        parts = new string[] { parts[0], parts[1], parts[2], lastPart };
                    }

                    if (parts.Length == 4)
                    {
                        TimeSpan time;
                        int      sessionId;
                        bool     isReceive;
                        if (TryParseDataStreamLine(parts, out time, out sessionId, out isReceive))
                        {
                            string dataPart = parts[3];

                            if (dataPart.StartsWith("Session Created"))
                            {
                                var sessionInfoParts    = dataPart.Split(';');
                                RawMessageFormat format = RawMessageFormat.JSON;

                                if (sessionInfoParts.Length >= 3)
                                {
                                    string   formatStr   = sessionInfoParts[2];
                                    string[] formatParts = formatStr.Split(':');
                                    format = (RawMessageFormat)Enum.Parse(typeof(RawMessageFormat), formatParts[1].Trim());
                                }

                                currentSession = new StreamSession(sessionId, dataPart, time, format);
                                sessions.Add(sessionId, currentSession);
                            }
                            else if (dataPart.StartsWith("Session Terminated"))
                            {
                                currentSession.TerminatedAt = time;
                            }
                            else if (dataPart.StartsWith("[Dismiss invalid session message]"))
                            {
                                errors.AppendLine("Packet received without valid session!");
                                errors.AppendLine(line);
                                errors.AppendLine();
                                continue;
                            }
                            else if (!dataPart.StartsWith("[Logger Stopped]"))
                            {
                                if (currentSession == null || currentSession.SessionId != sessionId)
                                {
                                    if (!sessions.TryGetValue(sessionId, out currentSession))
                                    {
                                        if (!ignoreSessions.Contains(sessionId))
                                        {
                                            errors.Append("Session ID ");
                                            errors.Append(sessionId);
                                            errors.AppendLine(" not found! All messages from this session are ignored!");

                                            ignoreSessions.Add(sessionId);
                                        }
                                        continue;
                                    }
                                }

                                IGenericMessage message = ParseMessage(dataPart, currentSession.Format);

                                // Flow rate
                                if (currentSession.PendingFlowRate == null)
                                {
                                    currentSession.PendingFlowRate = new FlowRate(time.Hours, time.Minutes, time.Seconds);
                                    currentSession.PendingFlowRate.StartLineNumber = lineNumber;
                                }
                                else if (currentSession.PendingFlowRate.Time.Hours != time.Hours ||
                                         currentSession.PendingFlowRate.Time.Minutes != time.Minutes ||
                                         currentSession.PendingFlowRate.Time.Seconds != time.Seconds)
                                {
                                    // add pending flowrate and create new
                                    if (!flowRateFilter.HasValue || flowRateFilter <= currentSession.PendingFlowRate.TotalCallCount)
                                    {
                                        currentSession.FlowRates.Add(currentSession.PendingFlowRate);
                                    }

                                    currentSession.PendingFlowRate = new FlowRate(time.Hours, time.Minutes, time.Seconds);
                                    currentSession.PendingFlowRate.StartLineNumber = lineNumber;
                                }
                                var pendFlowRate = currentSession.PendingFlowRate;
                                pendFlowRate.TotalCallCount++;
                                pendFlowRate.PayloadByteCount += dataPart.Length;

                                // round trip determination
                                MethodInvokeRoundtrip methodInvokeReq  = null;
                                MethodInvokeRoundtrip methodInvokeResp = null;
                                switch (message.Type)
                                {
                                case MessageType.AsyncMethodInvokeRequest:

                                    if (isReceive)
                                    {
                                        currentSession.IncomingAsyncCallCount++;
                                        pendFlowRate.IncomingAsyncCallCount++;

                                        CheckReceiveRequestOrder(errors, currentSession, message);
                                    }
                                    else
                                    {
                                        currentSession.OutgoingAsyncCallCount++;
                                        pendFlowRate.OutgoingAsyncCallCount++;

                                        CheckSendRequestOrder(errors, currentSession, message);
                                    }

                                    break;

                                case MessageType.MethodInvokeRequest:

                                    methodInvokeReq             = new MethodInvokeRoundtrip();
                                    methodInvokeReq.IsReceive   = isReceive;
                                    methodInvokeReq.Request     = message;
                                    methodInvokeReq.RequestTime = time;

                                    if (isReceive)
                                    {
                                        currentSession.IncomingSyncCallCount++;
                                        currentSession.IncomingSyncCalls.Add(message.RequestId, methodInvokeReq);
                                        pendFlowRate.IncomingSyncCallCount++;

                                        CheckReceiveRequestOrder(errors, currentSession, message);
                                    }
                                    else
                                    {
                                        currentSession.OutgoingSyncCallCount++;
                                        currentSession.OutgoingSyncCalls.Add(message.RequestId, methodInvokeReq);
                                        pendFlowRate.OutgoingSyncCallCount++;

                                        CheckSendRequestOrder(errors, currentSession, message);
                                    }

                                    break;


                                case MessageType.MethodInvokeResponse:

                                    if (isReceive)
                                    {
                                        if (currentSession.OutgoingSyncCalls.TryGetValue(message.RequestId, out methodInvokeResp))
                                        {
                                            methodInvokeResp.Response     = message;
                                            methodInvokeResp.ResponseTime = time;

                                            if (roundTripTimeFilter.HasValue &&
                                                methodInvokeResp.RoundTripTime < roundTripTimeFilter)
                                            {
                                                currentSession.OutgoingSyncCalls.Remove(message.RequestId);
                                            }
                                        }
                                        else
                                        {
                                            errors.AppendLine("Incoming method invoke response could not be assigned to a request: ");
                                            errors.AppendLine(line);
                                            errors.AppendLine();
                                        }
                                    }
                                    else
                                    {
                                        if (currentSession.IncomingSyncCalls.TryGetValue(message.RequestId, out methodInvokeResp))
                                        {
                                            methodInvokeResp.Response     = message;
                                            methodInvokeResp.ResponseTime = time;

                                            if (roundTripTimeFilter.HasValue &&
                                                methodInvokeResp.RoundTripTime < roundTripTimeFilter)
                                            {
                                                currentSession.IncomingSyncCalls.Remove(message.RequestId);
                                            }
                                        }
                                        else
                                        {
                                            errors.AppendLine("Outgoing method invoke response could not be assigned to a incoming request: ");
                                            errors.AppendLine(line);
                                            errors.AppendLine();
                                        }
                                    }

                                    break;
                                }


                                // handle file export
                                if (fileExort != null)
                                {
                                    if (openFileExportStreams == null)
                                    {
                                        openFileExportStreams = new Dictionary <string, StreamWriter>();
                                    }

                                    if (fileExort.MessageNames.Where(mn => mn.Equals(message.Name)).Any())
                                    {
                                        bool isConditionMatching = true;
                                        if (fileExort.Conditions != null)
                                        {
                                            foreach (var cond in fileExort.Conditions)
                                            {
                                                string condValue = GetJsonSimpleStringValue(dataPart, cond.Key);

                                                if (cond.Value != condValue)
                                                {
                                                    isConditionMatching = false;
                                                    break;
                                                }
                                            }
                                        }

                                        if (isConditionMatching)
                                        {
                                            string fileExportGroupValues = string.Concat(fileExort.GroupByKeys.Select(gk => GetJsonSimpleStringValue(dataPart, gk) + "_"));
                                            //string fileExportGroupValue = GetJsonSimpleStringValue(dataPart, fileExort.GroupByKey);

                                            StreamWriter currentExportWriter = null;
                                            if (openFileExportStreams.TryGetValue(fileExportGroupValues, out currentExportWriter) == false)
                                            {
                                                if (Directory.Exists(fileExort.ExportDirectory) == false)
                                                {
                                                    Directory.CreateDirectory(fileExort.ExportDirectory);
                                                }

                                                string conditions     = string.Concat(fileExort.Conditions?.Select(cd => $"{cd.Key}-{cd.Value}_"));
                                                string groupKeyValues = string.Concat(fileExort.GroupByKeys?.Select(gk => $"{gk}-{GetJsonSimpleStringValue(dataPart, gk)}_"));

                                                string exportPath = Path.Combine(Path.GetFullPath(fileExort.ExportDirectory), $"{conditions}{groupKeyValues.TrimEnd('_')}.txt");

                                                if (File.Exists(exportPath))
                                                {
                                                    File.Delete(exportPath);
                                                }

                                                currentExportWriter = new StreamWriter(exportPath);

                                                openFileExportStreams.Add(fileExportGroupValues, currentExportWriter);
                                            }

                                            if (fileExort.SeparateOnKey != null)
                                            {
                                                string separateOnKeyValue = GetJsonSimpleStringValue(dataPart, fileExort.SeparateOnKey);

                                                if (separateOnKeyValue == fileExort.SeparateOnKeyValue)
                                                {
                                                    currentExportWriter.WriteLine(Environment.NewLine);
                                                    currentExportWriter.WriteLine(Environment.NewLine);
                                                }
                                            }

                                            ExportOnlyHandling(fileExort, line, isReceive, dataPart, currentExportWriter);

                                            if (methodInvokeReq != null && methodInvokeReq.ExportFileStream == null)
                                            {
                                                methodInvokeReq.ExportFileStream = currentExportWriter;
                                            }
                                        }
                                    }
                                    else if (methodInvokeResp != null &&
                                             methodInvokeResp.ExportFileStream != null)
                                    {
                                        // write response as well
                                        ExportOnlyHandling(fileExort, line, isReceive, dataPart, methodInvokeResp.ExportFileStream);
                                        methodInvokeResp.ExportFileStream = null;
                                    }
                                }
                            }
                        }
                        else
                        {
                            errors.AppendLine("Invalid data row: " + line);
                        }
                    }
                    else
                    {
                        errors.AppendLine("Invalid data row! Could not be splitted into 4 parts: " + line);
                    }

                    lineNumber++;

                    if (progressPercentage != null &&
                        (lineNumber % 30000) == 0)
                    {
                        double dblPercentage = 100d / totalFileSize * (double)streamReader.BaseStream.Position;
                        progressPercentage((int)dblPercentage);
                    }
                }

                if (openFileExportStreams != null)
                {
                    foreach (var fileStream in openFileExportStreams.Values)
                    {
                        fileStream.Close();
                    }
                }

                return(sessions.Values.ToList <StreamSession>());
            }
        }