// this method implements the H production for the grammar // H -> identifier I private ParseResult H(Field.Kind fieldKind, TraceAggregationConfig telConfigEntry, ref List <Token> identifierList) { // check for argument name first Token token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected field name", this.lexAnalyzer.Position)); } // checking semantics against manifest file ParseResult parseRes = this.semanticsAnalyzer.CheckManifestFieldKindAndDefinition(telConfigEntry.TaskName, telConfigEntry.EventName, token.Text, fieldKind, this.lexAnalyzer.Position); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // consume the argument name token this.lexAnalyzer.ConsumeToken(); identifierList.Add(token); // try finding more aggregation kinds return(this.I(fieldKind, telConfigEntry, ref identifierList)); }
// this method implements the C production for the grammar // C -> metric : D private ParseResult C(ref TraceAggregationConfig telConfigEntry) { // check for "metric" first Token token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier || Field.Kind.Metric != Field.CreateFieldKindFromName(token.Text)) { return(new ParseResult(ParseCode.SemanticsInvalidFieldKind, "Invalid field kind specified", this.lexAnalyzer.Position)); } // consume the identifier (metric) token this.lexAnalyzer.ConsumeToken(); // check for : token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Colon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected : ", this.lexAnalyzer.Position)); } // consume the : token this.lexAnalyzer.ConsumeToken(); return(this.D(Field.Kind.Metric, ref telConfigEntry)); }
// this method implements the D production for the grammar // D -> E F G private ParseResult D(Field.Kind fieldKind, ref TraceAggregationConfig telConfigEntry) { // try parsing E , i.e get the param names List <Token> fieldTokenList = new List <Token>(); ParseResult parseRes = this.E(fieldKind, telConfigEntry, ref fieldTokenList); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // get the field names List <Field> fieldParamList; parseRes = SemanticsAnalyzer.CreateFieldsFromTokenList(fieldTokenList, fieldKind, out fieldParamList); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // try parsing F , i.e get the aggregation kinds List <Token> aggregationParamList = new List <Token>(); parseRes = this.F(ref aggregationParamList); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // check if the aggregation kinds are valid List <Aggregation.Kinds> aggregationKindsList; parseRes = SemanticsAnalyzer.CreateAggregationKindsFromTokenList(aggregationParamList, fieldKind, out aggregationKindsList); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // sucessfully parsed the aggregation entry E F // setting the current aggregation entry telConfigEntry.AddAggregationEntries(fieldParamList, aggregationKindsList); // try to find a new aggregation G parseRes = this.G(ref telConfigEntry); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } return(new ParseResult(ParseCode.Success)); }
public EnvironmentTelemetry( string clusterType, string serviceFabricVersion, string clusterDevType) { // getting hardware information int processorCount; long physicalMemoryInKB; EnvironmentTelemetry.GetSystemInfo(out processorCount, out physicalMemoryInKB); // getting disk and drive info string disks = "[]"; string drives = "[]"; try { #if !DotNetCoreClrLinux && !DotNetCoreClrIOT disks = JsonConvert.SerializeObject(DiskInfoTelemetry.GetAllDisks()); drives = JsonConvert.SerializeObject(DriveInfoTelemetry.GetAllDrives()); #endif } catch (Exception e) { // catching any exception for safety in case it fails for some reason // otherwise it will crash DCA everytime and prevent other telemetry to be sent EnvironmentTelemetry.traceSource.WriteError(LogSourceId, "Failed trying to get information about disks and drives. {0}", e); } // getting OS information string operatingSystem; string operatingSystemVersion; EnvironmentTelemetry.GetOperatingSystemInfo(out operatingSystem, out operatingSystemVersion); // populating the properties list with arguments this.Properties = new Dictionary <string, string>(); this.Properties.Add(ClusterTypeStr, clusterType); this.Properties.Add(ServiceFabricVersionStr, serviceFabricVersion); this.Properties.Add(ClusterDevTypeStr, clusterDevType); this.Properties.Add(DisksStr, disks); this.Properties.Add(DrivesStr, drives); this.Properties.Add(OperatingSystemStr, operatingSystem); this.Properties.Add(OperatingSystemVersionStr, operatingSystemVersion); // populating the metrics list with arguments this.Metrics = new Dictionary <string, double>(); this.Metrics.Add(ProcessorCountStr, (double)processorCount); this.Metrics.Add(PhysicalMemoryInKBStr, (double)physicalMemoryInKB); this.TraceAggregationCfg = TraceAggregationConfig.CreateSnapshotTraceAggregatorConfig(TaskNameStr, EventNameStr, string.Empty, this.Properties.Keys, this.Metrics.Keys); }
// this method implements the G production for the grammar // G -> , A | \epsilon private ParseResult G(ref TraceAggregationConfig telConfigEntry) { // check for , first Token token = this.lexAnalyzer.GetCurrentToken(); // \epsilon case if (token.Id != TokenId.Comma) { return(new ParseResult(ParseCode.Success)); } // consume the , token this.lexAnalyzer.ConsumeToken(); return(this.A(ref telConfigEntry)); }
// this method implements the I production for the grammar // I -> , H | \epsilon private ParseResult I(Field.Kind fieldKind, TraceAggregationConfig telConfigEntry, ref List <Token> identifierList) { // check for , first Token token = this.lexAnalyzer.GetCurrentToken(); // \epsilon case if (token.Id != TokenId.Comma) { return(new ParseResult(ParseCode.Success, string.Empty, this.lexAnalyzer.Position)); } // consume the , token this.lexAnalyzer.ConsumeToken(); return(this.H(fieldKind, telConfigEntry, ref identifierList)); }
// This method starts the parsing of a new line in the input configuration file // this method implements the // L -> Comment | EOL | T private ParseResult L(out TraceAggregationConfig telConfigEntry) { telConfigEntry = null; // getting next Token; Token token = this.lexAnalyzer.GetCurrentToken(); // check for EmptyLine first if (token.Id == TokenId.EOL) { return(new ParseResult(ParseCode.EmptyLine)); } if (token.Id == TokenId.Comment) { return(new ParseResult(ParseCode.Comment)); } return(this.T(out telConfigEntry)); }
private static EventTelemetry ConvertAggregationToTelemetry(TraceAggregationConfig traceAggregationConfig, TraceAggregator traceAggregator, TelemetryIdentifiers telemetryIds, int telBatchesDaily, int telBatchNumber) { EventTelemetry eventEntity = AppInsightsTelemetryWriter.CreateBaseEventTelemetry(telemetryIds, traceAggregationConfig.TaskName, traceAggregationConfig.EventName, telBatchesDaily, telBatchNumber, traceAggregator.TraceTimestamp); Dictionary <string, string> properties; Dictionary <string, double> metrics; traceAggregator.CurrentFormattedFieldAggregationsValues(out properties, out metrics); foreach (var property in properties) { eventEntity.Properties[property.Key] = property.Value; } foreach (var metric in metrics) { eventEntity.Metrics[metric.Key] = metric.Value; } return(eventEntity); }
// this method implements the E production for the grammar // E -> ( H ) private ParseResult E(Field.Kind fieldKind, TraceAggregationConfig telConfigEntry, ref List <Token> identifierList) { // check for ( first Token token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.OpenParenthesis) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected (", this.lexAnalyzer.Position)); } // consume the ( token this.lexAnalyzer.ConsumeToken(); // try parsing H , i.e get the param names List <string> fieldParamList = new List <string>(); ParseResult parseRes = this.H(fieldKind, telConfigEntry, ref identifierList); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // A semantics check could be done here later against the trace manifest file // check for ) token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.CloseParenthesis) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected )", this.lexAnalyzer.Position)); } // consume the ) token this.lexAnalyzer.ConsumeToken(); return(new ParseResult(ParseCode.Success)); }
public TelemetryPerformanceInstrumentation() { string[] metrics = new string[] { ProcessingEventsMeasuredTimeStr }; string[] properties = new string[] { }; List <Aggregation.Kinds> metricAggr = new List <Aggregation.Kinds>() { Aggregation.Kinds.Snapshot, Aggregation.Kinds.Minimum, Aggregation.Kinds.Maximum, Aggregation.Kinds.Count, Aggregation.Kinds.Sum, Aggregation.Kinds.Average, Aggregation.Kinds.Variance }; this.TraceAggregationCfg = TraceAggregationConfig.CreateTraceAggregatorConfig( TaskNameStr, EventNameStr, string.Empty, properties, new List <Aggregation.Kinds>(), metrics, metricAggr); }
// this method implements the B production for the grammar // A -> B | C private ParseResult A(ref TraceAggregationConfig telConfigEntry) { // check for "string" first Token token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Identifier expected", this.lexAnalyzer.Position)); } Field.Kind fieldKind = Field.CreateFieldKindFromName(token.Text); switch (fieldKind) { case Field.Kind.Property: return(this.B(ref telConfigEntry)); case Field.Kind.Metric: return(this.C(ref telConfigEntry)); default: return(new ParseResult(ParseCode.SemanticsInvalidFieldKind, "Invalid field kind specified - Expecting \"metric\" or \"property\"", this.lexAnalyzer.Position)); } }
public void TestMetricsAggregations() { // initializing the configuration of the aggregation for a single field with all types of aggregation string[] properties = { }; string[] metrics = { "metric1", "metric2" }; Aggregation.Kinds[] aggrKindsProperties = { }; Aggregation.Kinds[] aggrKindsMetrics = { Aggregation.Kinds.Average, Aggregation.Kinds.Count, Aggregation.Kinds.Maximum, Aggregation.Kinds.Minimum, Aggregation.Kinds.Snapshot, Aggregation.Kinds.Sum, Aggregation.Kinds.Variance }; TraceAggregationConfig traceAggrconfig = TraceAggregationConfig.CreateTraceAggregatorConfig( "TestTaskName", "TestEventName", string.Empty, properties, aggrKindsProperties, metrics, aggrKindsMetrics); // create the trace aggregator TraceAggregator traceAggr = new TraceAggregator(traceAggrconfig); // creating some metric values to test the aggregations KeyValuePair <string, double>[] metricValues = { new KeyValuePair <string, double>("metric1", 0.0), new KeyValuePair <string, double>("metric2", 1.0) }; // aggregating traceAggr.Aggregate(metricValues); Dictionary <string, double> metricResults; Dictionary <string, string> propResults; traceAggr.CurrentFormattedFieldAggregationsValues(out propResults, out metricResults); // checking whether metric values are properly set Assert.AreEqual(0.0, metricResults["metric1_Snapshot"]); Assert.AreEqual(1.0, metricResults["metric1_Count"]); Assert.AreEqual(0.0, metricResults["metric1_Minimum"]); Assert.AreEqual(0.0, metricResults["metric1_Maximum"]); Assert.AreEqual(0.0, metricResults["metric1_Sum"]); Assert.AreEqual(0.0, metricResults["metric1_Average"]); Assert.AreEqual(0.0, metricResults["metric1_Variance"]); Assert.AreEqual(1.0, metricResults["metric2_Snapshot"]); Assert.AreEqual(1.0, metricResults["metric2_Count"]); Assert.AreEqual(1.0, metricResults["metric2_Minimum"]); Assert.AreEqual(1.0, metricResults["metric2_Maximum"]); Assert.AreEqual(1.0, metricResults["metric2_Sum"]); Assert.AreEqual(1.0, metricResults["metric2_Average"]); Assert.AreEqual(0.0, metricResults["metric2_Variance"]); // creating second set of metrics to test the aggregations KeyValuePair <string, double>[] metricValues2 = { new KeyValuePair <string, double>("metric1", -1.0), new KeyValuePair <string, double>("metric2", 2.0), new KeyValuePair <string, double>("metric3", 3.0) }; traceAggr.Aggregate(metricValues2); traceAggr.CurrentFormattedFieldAggregationsValues(out propResults, out metricResults); Assert.AreEqual(-1.0, metricResults["metric1_Snapshot"]); Assert.AreEqual(2.0, metricResults["metric1_Count"]); Assert.AreEqual(-1.0, metricResults["metric1_Minimum"]); Assert.AreEqual(0.0, metricResults["metric1_Maximum"]); Assert.AreEqual(-1.0, metricResults["metric1_Sum"]); Assert.AreEqual(-0.5, metricResults["metric1_Average"]); Assert.AreEqual(0.5, metricResults["metric1_Variance"]); Assert.AreEqual(2.0, metricResults["metric2_Snapshot"]); Assert.AreEqual(2.0, metricResults["metric2_Count"]); Assert.AreEqual(1.0, metricResults["metric2_Minimum"]); Assert.AreEqual(2.0, metricResults["metric2_Maximum"]); Assert.AreEqual(3.0, metricResults["metric2_Sum"]); Assert.AreEqual(1.5, metricResults["metric2_Average"]); Assert.AreEqual(0.5, metricResults["metric2_Variance"]); // checking whether "metric3" which is not part of of the configuration added values Assert.AreEqual(14, metricResults.Values.Count); // checking whether any value was added by mistake to the properties Assert.IsTrue(propResults.Count == 0); }
public void TestPropertiesAggregations() { // initializing the configuration of the aggregation for a single field with all types of aggregation string[] properties = { "prop1", "prop2", "prop3", "prop4" }; string[] metrics = { }; Aggregation.Kinds[] aggrKindsProperties = { Aggregation.Kinds.Count, Aggregation.Kinds.Snapshot }; Aggregation.Kinds[] aggrKindsMetrics = { }; TraceAggregationConfig traceAggrconfig = TraceAggregationConfig.CreateTraceAggregatorConfig( "TestTaskName", "TestEventName", string.Empty, properties, aggrKindsProperties, metrics, aggrKindsMetrics); // create the trace aggregator TraceAggregator traceAggr = new TraceAggregator(traceAggrconfig); // creating some property values to test the aggregations KeyValuePair <string, double>[] metricValues = { }; KeyValuePair <string, string>[] propertyValues = { new KeyValuePair <string, string>("prop1", null), new KeyValuePair <string, string>("prop2", string.Empty), new KeyValuePair <string, string>("prop3", "test1"), new KeyValuePair <string, string>("prop4", "test2") }; // aggregating traceAggr.Aggregate(propertyValues); Dictionary <string, double> metricResults; Dictionary <string, string> propResults; traceAggr.CurrentFormattedFieldAggregationsValues(out propResults, out metricResults); // checking whether metric values are properly set Assert.AreEqual(null, propResults["prop1_Snapshot"]); Assert.AreEqual(string.Empty, propResults["prop2_Snapshot"]); Assert.AreEqual("test1", propResults["prop3_Snapshot"]); Assert.AreEqual("test2", propResults["prop4_Snapshot"]); // the count should go to the metrics since it is a number Assert.IsFalse(propResults.ContainsKey("prop1_Count")); Assert.IsFalse(propResults.ContainsKey("prop2_Count")); Assert.IsFalse(propResults.ContainsKey("prop3_Count")); Assert.IsFalse(propResults.ContainsKey("prop4_Count")); // checks that all have count of 1 Assert.AreEqual(1.0, metricResults["prop1_Count"]); Assert.AreEqual(1.0, metricResults["prop2_Count"]); Assert.AreEqual(1.0, metricResults["prop3_Count"]); Assert.AreEqual(1.0, metricResults["prop4_Count"]); // creating second set of propertis to test the aggregations KeyValuePair <string, string>[] propertyValues2 = { new KeyValuePair <string, string>("prop4", "test2NewValue"), new KeyValuePair <string, string>("prop5", "notPartOfAggregator") }; traceAggr.Aggregate(propertyValues2); traceAggr.CurrentFormattedFieldAggregationsValues(out propResults, out metricResults); // checking whether new values are properly set prop1, prop2, prop3 should have the same value Assert.AreEqual(null, propResults["prop1_Snapshot"]); Assert.AreEqual(string.Empty, propResults["prop2_Snapshot"]); Assert.AreEqual("test1", propResults["prop3_Snapshot"]); Assert.AreEqual("test2NewValue", propResults["prop4_Snapshot"]); Assert.IsFalse(metricResults.ContainsKey("prop5_Count")); Assert.IsFalse(propResults.ContainsKey("prop5_Count")); Assert.IsFalse(propResults.ContainsKey("prop5_Snapshot")); // checks that all have count of 1 but prop4 which should have 2 Assert.AreEqual(1.0, metricResults["prop1_Count"]); Assert.AreEqual(1.0, metricResults["prop2_Count"]); Assert.AreEqual(1.0, metricResults["prop3_Count"]); Assert.AreEqual(2.0, metricResults["prop4_Count"]); // checking whether "metric3" which is not part of of the configuration added values Assert.AreEqual(4, metricResults.Values.Count); Assert.AreEqual(4, propResults.Values.Count); }
public static bool ReadFieldsFromEventRecord( EventRecord eventRecord, EventDefinition eventDefinition, TraceAggregationConfig traceAggregationConfig, out List <KeyValuePair <string, double> > numericalFields, out List <KeyValuePair <string, string> > stringFields, out string diffFieldValueString, string logSourceId) { numericalFields = new List <KeyValuePair <string, double> >(); stringFields = new List <KeyValuePair <string, string> >(); diffFieldValueString = string.Empty; // Figure out how many fields the event has int fieldCount = eventDefinition.Fields.Count; if (0 == fieldCount) { Utility.TraceSource.WriteError( logSourceId, "No fields found in event of type {0}.{1}.", eventDefinition.TaskName, eventDefinition.EventName); return(false); } // Get the field names and values try { ApplicationDataReader reader = new ApplicationDataReader( eventRecord.UserData, eventRecord.UserDataLength); foreach (FieldDefinition fieldDef in eventDefinition.Fields) { var fieldValue = TelemetryUtility.GetEtwEventRecordValue(reader, fieldDef, logSourceId); if (traceAggregationConfig.FieldsAndAggregationConfigs.ContainsKey(fieldDef.Name)) { if (null != fieldValue) { if (fieldValue is string) { stringFields.Add(new KeyValuePair <string, string>(fieldDef.Name, (string)fieldValue)); } else { if (fieldValue is double) { numericalFields.Add(new KeyValuePair <string, double>(fieldDef.Name, (double)fieldValue)); } else { Utility.TraceSource.WriteError( logSourceId, "Unexpected field value type read. TaskName : {0}, EventName : {1}, FieldName : {2}, FieldType : {3}", eventDefinition.TaskName, eventDefinition.EventName, fieldDef.Name, fieldDef.Type.ToString()); } } } } // look if field is the differentiator field if (traceAggregationConfig.DifferentiatorFieldName == fieldDef.Name) { if (null != fieldValue) { diffFieldValueString = fieldValue.ToString(); } } } } catch (Exception e) { Utility.TraceSource.WriteError( logSourceId, "Failed to get all the fields of event of type {0}.{1}. Exception info: {2}.", eventDefinition.TaskName, eventDefinition.EventName, e); return(false); } return(true); }
// extension method for telemetryCollection to aggregate from EventRecord public static void AggregateEventRecord(this TelemetryCollection telemetryCollection, EventRecord eventRecord, EventDefinition eventDefinition, TraceAggregationConfig traceAggregationConfig, string logSourceId) { // Reading data from eventRecord white-listed fields List <KeyValuePair <string, double> > numericalFields; List <KeyValuePair <string, string> > stringFields; string diffFieldValueString; TelemetryUtility.ReadFieldsFromEventRecord(eventRecord, eventDefinition, traceAggregationConfig, out numericalFields, out stringFields, out diffFieldValueString, logSourceId); telemetryCollection.Aggregate(traceAggregationConfig, diffFieldValueString, numericalFields, stringFields, DateTime.FromFileTimeUtc(eventRecord.EventHeader.TimeStamp)); }
// checks whether the trace is whitelisted - if so outputs the traceAggregationConfig for the trace public bool TryGetWhitelist(string taskName, string eventName, out TraceAggregationConfig traceAggregationConfig) { // see if taskname and eventname are whitelisted and get aggregation configuration return(this.whiteListedEventsFromConfigFile.TryGetValue(Tuple.Create(taskName, eventName), out traceAggregationConfig)); }
// this method implements the T production for the grammar // T -> T_t ; identifier ; identifier ; identifier ; A private ParseResult T(out TraceAggregationConfig telConfigEntry) { telConfigEntry = null; // getting next Token; Token token = this.lexAnalyzer.GetCurrentToken(); // T_t should be 's' if (token.Id != TokenId.Identifier) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected u|s", this.lexAnalyzer.Position)); } if (token.Text != "s") { return(new ParseResult(ParseCode.NotImplemented, "Unstructured trace not implemented yet.", this.lexAnalyzer.Position)); } // look for ; this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Semicolon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected ;", this.lexAnalyzer.Position)); } // look for TaskName this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected name of TaskName", this.lexAnalyzer.Position)); } // save the Task name in TelemetryConfigEntry string telConfigEntryTaskName = token.Text; // look for ; this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Semicolon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected ;", this.lexAnalyzer.Position)); } // look for the EventName this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected name of EventName", this.lexAnalyzer.Position)); } // save the Event name in TelemetryConfigEntry string telConfigEntryEventName = token.Text; // look for ; this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Semicolon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected ;", this.lexAnalyzer.Position)); } // semantics - check whether the event is defined in the etw manifest file ParseResult parseRes = this.semanticsAnalyzer.CheckManifestEventDefinition(telConfigEntryTaskName, telConfigEntryEventName, this.lexAnalyzer.Position); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // look for Diffentiator name which can be empty this.lexAnalyzer.ConsumeToken(); token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Identifier && token.Id != TokenId.Semicolon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected name of field to be used as differentiator", this.lexAnalyzer.Position)); } // save the Task name in TelemetryConfigEntry string telConfigEntryDifferentiatorFieldName; if (token.Id == TokenId.Identifier) { // only consume token if not empty this.lexAnalyzer.ConsumeToken(); telConfigEntryDifferentiatorFieldName = token.Text; } else { telConfigEntryDifferentiatorFieldName = string.Empty; } // semantics - check whether the differentiator field exists in the manifest file in case it is provided in the config file if (telConfigEntryDifferentiatorFieldName != string.Empty) { parseRes = this.semanticsAnalyzer.CheckManifestFieldDefinition(telConfigEntryTaskName, telConfigEntryEventName, telConfigEntryDifferentiatorFieldName, this.lexAnalyzer.Position); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } } // construct the TraceAggregationConfig with the parsed TaskName, EventName, DifferentiatorField telConfigEntry = new TraceAggregationConfig(telConfigEntryTaskName, telConfigEntryEventName, telConfigEntryDifferentiatorFieldName); // look for Semicolon ; token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.Semicolon) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected ;", this.lexAnalyzer.Position)); } this.lexAnalyzer.ConsumeToken(); // try to parse the aggregation information parseRes = this.A(ref telConfigEntry); if (parseRes.ParseCode != ParseCode.Success) { return(parseRes); } // look for EmptyLine token = this.lexAnalyzer.GetCurrentToken(); if (token.Id != TokenId.EOL) { return(new ParseResult(ParseCode.ErrorUnexpectedToken, "Expected End of line", this.lexAnalyzer.Position)); } this.lexAnalyzer.ConsumeToken(); return(new ParseResult(ParseCode.Success)); }