/// <summary> /// Extract the results and put it into transactionDetails: cnt, min, max, avg, stdev /// </summary> /// <param name="line"></param> private TransactionValue ExtractTrsDetailsCSV(string line) { //sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_95%_line,aggregate_report_99%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth,aggregate_report_stddev //setUp: bsh.shared.zoekgob,1,1697,1697,1697,1697,1697,1697,1697,"0,00%",",6",",0","0,00" string cLine = CorrectJmeterCSVLine(line); string[] parts = cLine.Split(','); // wat nog mist is toevoegen van een lege regel als alles fout gegaan is TransactionValue value = new TransactionValue(); string executed = parts[1]; value.cnt = parts[1]; string cntExecuted = parts[1]; value.avg = Utils.jmeterTimeToIntermediateSecondsString(parts[2]); value.median = Utils.jmeterTimeToIntermediateSecondsString(parts[3]); value.p90 = Utils.jmeterTimeToIntermediateSecondsString(parts[4]); value.p95 = Utils.jmeterTimeToIntermediateSecondsString(parts[5]); //6=99p not present in csv but not really useable as an application perf metric value.min = Utils.jmeterTimeToIntermediateSecondsString(parts[7]); value.max = Utils.jmeterTimeToIntermediateSecondsString(parts[8]); value.fail = NormalizeFail(Utils.NormalizeFloatString(parts[9].TrimEnd('%')), cntExecuted); value.stdev = Utils.jmeterTimeToIntermediateSecondsString(parts[12]); return(value); }
/// <summary> /// Add measure to existing or new transaction line (count canceled trs) /// </summary> /// <param name="line"></param> /// <param name="trsName"></param> private void ExtractAddTrsMeasureCSV(string line, string trsName) { //C;Measure group;Name;Measure type;N;Sum;Min;Max;StdDev;Avg;MinSum;MaxSum;MinMax;MaxMin;MinAvg;MaxAvg;MinCnt;MaxCnt //;Transaction;LoketControle_01_inloggen;Trans.(busy) ok[s];4;6,72400000;1,56000000;1,82500000;0,09698711;1,68100000;1,56000000;1,82500000;1,56000000;1,82500000;1,56000000;1,82500000;1,00000000;1,00000000 if (!_transactionDetails.items.ContainsKey(trsName)) { _transactionDetails.items.Add(trsName, TransactionValue.CreateEmptyValue()); } TransactionValue value = new TransactionValue(_transactionDetails.items[trsName]); string[] parts = line.Split(';'); // failed if (line.Contains(TRSFAILEDSUBSTRING)) { value.fail = parts[4]; } // canceled if (line.Contains(TRSCANCELEDSUBSTRING)) { value.cancel = parts[4]; } _transactionDetails.items[trsName] = value.ToString(); //Log.WriteLine("csv data extracted: "+trsName + "=" + value.ToString()); }
public Income(Guid userId, string name, string category, DateTime date, TransactionValue value) : this() { if (string.IsNullOrEmpty(name)) { throw new Error.IncomeMustHaveName(); } this.Name = name; this.Date = date; this.UserId = userId; if (value == null) { throw new Error.IncomeTransactionValueCannotBeNull(); } this.Value = value; if (!Enum.TryParse(typeof(IncomeCategory), category, out var categoryEnum)) { categoryEnum = IncomeCategory.Other; } this.Category = (IncomeCategory)categoryEnum; }
public Income AddIncome(string name, string category, DateTime date, TransactionValue value) { var newIncome = new Income(this.Id, name, category, date, value); this._incomes.Add(newIncome); return(newIncome); }
internal static Income WithRecurrency(Guid userId, string name, string category, DateTime date, TransactionValue value, Guid recurrentIncomeId) { var newIncome = new Income(userId, name, category, date, value); newIncome.RecurrentIncomeId = recurrentIncomeId; return(newIncome); }
public Income EditIncome(Guid id, string name, DateTime date, TransactionValue value) { var foundIncome = this._incomes.FirstOrDefault(i => i.Id == id); if (foundIncome == null) { throw new Error.IncomeNotFound(); } foundIncome.Update(name, date, value); return(foundIncome); }
public Expense(Guid userId, string name, string category, DateTime date, TransactionValue value) : this() { this.Validate(userId, name, date, value); this.Date = date; this.Name = name; this.Value = value; this.UserId = userId; if (!Enum.TryParse(typeof(ExpenseCategory), category, out var categoryEnum)) { this.Category = ExpenseCategory.Others; } this.Category = (ExpenseCategory)categoryEnum; }
/// <summary> /// Generate aggregate data (total faults, average of percentiles...) /// </summary> /// <param name="parameters"></param> public void GenerateAggregates(ParamInterpreter parameters) { int cnt = 0; Log.WriteLine("generate aggregated data..."); // scrape and aggregate data from transaction data TransactionValueAggregate transactionAggregate = new TransactionValueAggregate(); // foreach transactionlines (evaluate only successful transactions, leave faulty ones away from aggregation) foreach (string transactionName in _transactionNames) { // only include in agggregation if transactionname matches 'report transacton name pattern' if (IsSummarizeTransaction(transactionName) && _transactionDetails.items.ContainsKey(transactionName)) { TransactionValue trs = new TransactionValue(_transactionDetails.items[transactionName]); transactionAggregate.AddTransaction(trs); cnt++; } } // give up if no summarizable transactions found (try to prevent weird crashes lateron) if (0 == cnt) { string msg = "no transaction names found that meet naming convention (" + REPORTTRANSACTIONNAMEPATTERN + ")"; Log.WriteLine("SEVERE: " + msg); throw new Exception(msg); } transactionAggregate.Aggregate(); // write aggregated transaction line _transactionDetails.Add(AGGREGATEDTRSNAME, transactionAggregate.ToString()); // isolate most important values as variable for history graph -> measure format (later to variable category?) _variables.Add(AVGOF90PERCENTILES, Utils.ToMeasureFormatString(transactionAggregate.p90)); _variables.Add(AVGOFMEDIAN, Utils.ToMeasureFormatString(transactionAggregate.median)); _variables.Add(AVGOF95PERCENTILES, Utils.ToMeasureFormatString(transactionAggregate.p95)); _variables.Add(AVGOFAVERAGES, Utils.ToMeasureFormatString(transactionAggregate.avg)); _variables.Add(TRANSACTIONSFAILED, transactionAggregate.fail); // old, can be deleted in time (replaced by transactionssuccess) // _variables.Add(TRANSACTIONSTOTAL, transactionAggregate.cnt); _variables.Add(TRANSACTIONSTOTAL, AddIntStrings(transactionAggregate.cnt, transactionAggregate.fail)); _variables.Add(TRANSACTIONSSUCCESS, transactionAggregate.cnt); // is new Log.WriteLine(string.Format("{0} of {1} transactions aggregated", cnt, _transactionNames.Length)); }
/// <summary> /// Min, max, avg, cnt transactiondata /// </summary> /// <param name="lines"></param> /// <param name="trsNames"></param> private TransactionDetails ReadTransactionDetailsFromCSV(string[] lines, string[] trsNames) { string trsName; TransactionDetails td = new TransactionDetails(); foreach (string line in lines) { trsName = Utils.NormalizeTransactionName(line.Split(',')[0]); if (trsNames.Contains(trsName)) { TransactionValue value = ExtractTrsDetailsCSV(line); td.Add(trsName, value.ToString()); } } return(td); }
/// <summary> /// Extract percentile data from trs summary in bpr/xml /// </summary> /// <param name="xml"></param> /// <param name="trsName"></param> private void ExtractAddTrsDetailsXML(string xml, string trsName) { //string p90 = Regex.Match(xml, @"nr=""90""><Height>(.*?)</Height").Groups[1].Value; if (!_transactionDetails.items.ContainsKey(trsName)) { throw new Exception(string.Format("Transaction [{0}] not found in XML/BRP, cannot add percentile data.", trsName)); } TransactionValue value = new TransactionValue(_transactionDetails.items[trsName]); // 50, 90 and 99 percentiles are the most used and easily available, the rest can be calculated by interpolation value.median = Regex.Match(xml, @"nr=""50""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0'); value.p90 = Regex.Match(xml, @"nr=""90""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0'); value.p95 = Regex.Match(xml, @"nr=""95""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0'); _transactionDetails.items[trsName] = value.ToString(); //Log.WriteLine(trsName+" brp data extracted, 90p is : "+value.p90); }
/// <summary> /// Extract the results and put it into transactionDetails: cnt, min, max, avg, stdev /// </summary> /// <param name="line"></param> /// <param name="trsName"></param> private void ExtractTrsDetailsCSV(string line, string trsName) { //C;Measure group;Name;Measure type;N;Sum;Min;Max;StdDev;Avg;MinSum;MaxSum;MinMax;MaxMin;MinAvg;MaxAvg;MinCnt;MaxCnt //;Transaction;LoketControle_01_inloggen;Trans.(busy) ok[s];4;6,72400000;1,56000000;1,82500000;0,09698711;1,68100000;1,56000000;1,82500000;1,56000000;1,82500000;1,56000000;1,82500000;1,00000000;1,00000000 //;Timer;DR_01_OpenDonorregister;Response time[s];1;0,80400000;0,80400000;0,80400000;0,00000000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;1,00000000;1,00000000 string[] parts = line.Split(';'); // wat nog mist is toevoegen van een lege regel als alles fout gegaan is TransactionValue value = new TransactionValue(); value.cnt = parts[4]; value.min = parts[6].TrimEnd('0'); value.avg = parts[9].TrimEnd('0'); value.max = parts[7].TrimEnd('0'); value.stdev = parts[8].TrimEnd('0'); _transactionDetails.Add(trsName, value.ToString()); Log.WriteLine(trsName + "=" + value.ToString()); }
private void Validate(Guid userId, string name, DateTime date, TransactionValue value) { if (userId == Guid.Empty) { throw new Error.ExpenseMustHaveUserId(); } if (string.IsNullOrEmpty(name)) { throw new Error.ExpenseMustHaveName(); } if (date < DateTime.Now.AddYears(-100)) { throw new Error.ExpenseCannotBeOlderThanOneHundredYears(); } if (value == null) { throw new Error.ExpenseTransactionValueCannotBeNull(); } }
/// <summary> /// Merge fault data from 'all' transaction data into 'success' transaction data /// </summary> /// <param name="successTransactionDetails"></param> /// <param name="allTransactionDetails"></param> private void MergeFaultData(TransactionDetails successTransactionDetails, TransactionDetails allTransactionDetails) { // iterate over list of all transactions (allTransactionDetails) foreach (string trsName in allTransactionDetails.items.GetKeys()) { // if found in successTransactionDetails: some exceptions, so: add only num of faults to existing success story if (successTransactionDetails.items.ContainsKey(trsName)) { // create working object for source- and target data TransactionValue allValue = new TransactionValue(allTransactionDetails.items[trsName]); TransactionValue successValue = new TransactionValue(successTransactionDetails.items[trsName]); // if all fail (success=0): clear stats if (successValue.cnt == "0") { successValue = new TransactionValue(); } // if faults have occured -> calculate fault field if (!successValue.cnt.Equals(allValue.cnt, StringComparison.Ordinal)) { successValue.fail = SubtractStrInt(allValue.cnt, successValue.cnt); _transactionDetails.items[trsName] = successValue.ToString(); // replace num of failed Log.WriteLine(string.Format("fault data: {0} faults added to {1}", successValue.fail, trsName)); } } // if not found in successTransactionDetails: 100% exception, so: add empty row with only number of faults else { TransactionValue newSuccessValue = new TransactionValue(); TransactionValue allValue = new TransactionValue(allTransactionDetails.items[trsName]); // only fill failed field from allvalue (=failed) newSuccessValue.fail = allValue.cnt; _transactionDetails.Add(trsName, newSuccessValue.ToString()); Log.WriteLine(string.Format("fault data: no-stats result ({0} faults) for {1}", newSuccessValue.fail, trsName)); } } }
public RecurrentExpense(Guid userId, string name, string category, DateTime date, TransactionValue value, DateTime until, int frequency) : this() { this.Recurrency = new Recurrency(Frequency.FromValue(frequency), until); this._expenses.Add(new Expense(userId, name, category, date, value, this.Id)); foreach (var nextDate in this.Recurrency.DatesUntilRecurrencyEndsByFrequency(date)) { this._expenses.Add(new Expense(userId, name, category, nextDate, value, this.Id)); } }
internal void Update(Guid userId, string name, ExpenseCategory category, DateTime date, TransactionValue value) { this.Validate(userId, name, date, value); this.Name = name; this.Category = category; this.Date = date; this.Value = value; }
internal Expense(Guid userId, string name, string category, DateTime date, TransactionValue value, Guid recurrentExpenseId) : this(userId, name, category, date, value) { this.RecurrentExpenseId = recurrentExpenseId; }
public Expense EditExpense(Guid id, string name, Expense.ExpenseCategory category, DateTime date, TransactionValue value) { var foundExpense = this._expenses.FirstOrDefault(e => e.Id == id); if (foundExpense == null) { throw new Error.ExpenseNotFound(); } foundExpense.Update(this.Id, name, category, date, value); return(foundExpense); }
public void Update(string name, DateTime date, TransactionValue value) { this.Name = name; this.Date = date; this.Value = value; }