}; //ascii 58--64 + misc. //Process a tuple from the stream public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); try { var words = tuple.GetString(0).ToLower().Split(_punctuationChars); int sentimentScore = CalcSentimentScore(words); var word_pairs = words.Take(words.Length - 1) .Select((word, idx) => string.Format("{0} {1}", word, words[idx + 1])); var all_words = words.Concat(word_pairs).ToList(); // Emit all index entries for counting and writing downstream foreach (var word in all_words) { this.ctx.Emit(new Values(word, tuple.GetLong(1), tuple.GetString(2), tuple.GetString(3), tuple.GetString(4), sentimentScore)); } } catch (Exception ex) { Context.Logger.Error("SentimentIndexerBolt Exception: " + ex.Message + "\nStackTrace: \n" + ex.StackTrace); } Context.Logger.Info("Execute exit"); }
':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~' }; //ascii 58--64 + misc. //Process a tuple from the stream public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); try { var words = tuple.GetString(0).ToLower().Split(_punctuationChars); int sentimentScore = CalcSentimentScore(words); var word_pairs = words.Take(words.Length - 1) .Select((word, idx) => string.Format("{0} {1}", word, words[idx + 1])); var all_words = words.Concat(word_pairs).ToList(); // Emit all index entries for counting and writing downstream foreach (var word in all_words) { this.ctx.Emit(new Values(word, tuple.GetLong(1), tuple.GetString(2), tuple.GetString(3), tuple.GetString(4), sentimentScore)); } } catch (Exception ex) { Context.Logger.Error("SentimentIndexerBolt Exception: " + ex.Message + "\nStackTrace: \n" + ex.StackTrace); } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string streamId = tuple.GetSourceStreamId(); switch (streamId) { case SentenceGenerator.STREAM_ID: { string sentence = tuple.GetString(0); Context.Logger.Info("sentence: {0}", sentence); } break; case PersonGenerator.STREAM_ID: { Person person = (Person)tuple.GetValue(0); Context.Logger.Info("person: {0}", person.ToString()); } break; default: Context.Logger.Info("Get unknown tuple from unknown stream."); break; } Context.Logger.Info("Execute exit"); }
public void Execute(SCPTuple tuple) { string json = tuple.GetString(0); var node = JObject.Parse(json); var temp = node.GetValue("temp"); JToken tempVal; if (node.TryGetValue("temp", out tempVal)) //assume must be a temperature reading { Context.Logger.Info("temp:" + temp.Value <double>()); JToken createDate = node.GetValue("createDate"); JToken deviceId = node.GetValue("deviceId"); _context.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple>() { tuple }, new List <object> { tempVal.Value <double>(), createDate.Value <string>(), deviceId.Value <string>() }); } _context.Ack(tuple); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { ctx.Ack(tuple); //Log tuple content Context.Logger.Warn(tuple.GetString(0)); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string word = tuple.GetString(0); int count = counts.ContainsKey(word) ? counts[word] : 0; count++; counts[word] = count; Context.Logger.Info("Emit: {0}, count: {1}", word, count); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple> { tuple }, new Values(word, count)); if (enableAck) { Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } // log some info to out file for bvt test validataion if (taskIndex == 0) // For component with multiple parallism, only one of them need to log info { string fileName = @"..\..\..\..\..\HelloWorldOutput" + Process.GetCurrentProcess().Id + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Append); using (StreamWriter writer = new StreamWriter(fs)) { writer.WriteLine("word: {0}, count: {1}", word, count); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string sentence = tuple.GetString(0); foreach (string word in sentence.Split(' ')) { Context.Logger.Info("Emit: {0}", word); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple> { tuple }, new Values(word, word[0])); } if (enableAck) { if (Sample(50)) // this is to demo how to fail tuple. We do it randomly { Context.Logger.Info("fail tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Fail(tuple); } else { if (Sample(50)) // this is to simulate timeout { Context.Logger.Info("sleep {0} seconds", msgTimeoutSecs + 1); Thread.Sleep((msgTimeoutSecs + 1) * 1000); } Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string word = tuple.GetString(0); int count = counts.ContainsKey(word) ? counts[word] : 0; count++; counts[word] = count; Context.Logger.Info("Emit: {0}, count: {1}", word, count); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(word, count)); if (enableAck) { Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } // log some info to out file for bvt test validataion if (taskIndex == 0) // For component with multiple parallism, only one of them need to log info { string fileName = @"..\..\..\..\..\HelloWorldOutput" + Process.GetCurrentProcess().Id + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Append); using (StreamWriter writer = new StreamWriter(fs)) { writer.WriteLine("word: {0}, count: {1}", word, count); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string sentence = tuple.GetString(0); foreach (string word in sentence.Split(' ')) { Context.Logger.Info("Emit: {0}", word); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(word, word[0])); } if (enableAck) { if (Sample(50)) // this is to demo how to fail tuple. We do it randomly { Context.Logger.Info("fail tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Fail(tuple); } else { if (Sample(50)) // this is to simulate timeout { Context.Logger.Info("sleep {0} seconds", msgTimeoutSecs+1); Thread.Sleep((msgTimeoutSecs + 1) * 1000); } Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { if (tuple.GetSourceStreamId().Equals(Constants.SYSTEM_TICK_STREAM_ID)) { Context.Logger.Info("Aggregates tuple values.."); foreach (var key in _data.Keys) { var avg = _data[key].Average(); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, tuplesToAck, new Values(key, avg)); } Context.Logger.Info("acking the batch: " + tuplesToAck.Count); foreach (var t in tuplesToAck) { this.ctx.Ack(t); } _data.Clear(); tuplesToAck.Clear(); } else { var sensorName = tuple.GetString(0); var value = tuple.GetDouble(1); if (!_data.ContainsKey(tuple.GetString(0))) { _data.Add(sensorName, new List <double>() { value }); } else { _data[sensorName].Add(value); } tuplesToAck.Enqueue(tuple); } }
public void Execute(SCPTuple tuple) { PowerBIClient.Do(api => { var isObjectInsert = api.Insert(datasetId, new Data.WordCount { Word = tuple.GetString(0), Count = tuple.GetInteger(1) }); }); }
// Called when a new tuple is available public void Execute(SCPTuple tuple) { // Get the sentance from the tuple string sentence = tuple.GetString(0); // Split at space characters foreach (string word in sentence.Split(' ')) { //Emit each word this.ctx.Emit(new Values(word)); } }
/// <summary> /// The Execute() function is called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { //Get the string data from the tuple string eventValue = tuple.GetString(0); if (eventValue != null) { //Log the data Context.Logger.Info("Received data: " + eventValue); //ACK the tuple so the spout knows it was processed //If we don't ACK, the EventHubSpout can stop receiving; it expects ACKs this.ctx.Ack(tuple); } }
public void Execute(SCPTuple tuple) { try { double tempReading = tuple.GetDouble(0); String createDate = tuple.GetString(1); String deviceId = tuple.GetString(2); if (tempReading > _maxAlertTemp) { _context.Emit(new Values( "reading above bounds", tempReading, createDate, deviceId )); Context.Logger.Info("Emitting above bounds: " + tempReading); } else if (tempReading < _minAlertTemp) { _context.Emit(new Values( "reading below bounds", tempReading, createDate, deviceId )); Context.Logger.Info("Emitting below bounds: " + tempReading); } _context.Ack(tuple); } catch (Exception ex) { Context.Logger.Error(ex.ToString()); } }
public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string sentence = tuple.GetString(0); // grab the first (and only field) from the tuple // tokenize it into words foreach (string word in sentence.Split(' ')) { // log each word and emit it into the output stream Context.Logger.Info("Emit: {0}", word); ctx.Emit(new Values(word)); } Context.Logger.Info("Execute exit"); }
// Called when a new tuple is available public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); // Get the sentence from the tuple string sentence = tuple.GetString(0); // Split at space characters foreach (string word in sentence.Split(' ')) { Context.Logger.Info("Emit: {0}", word); //Emit each word this.ctx.Emit(new Values(word)); } Context.Logger.Info("Execute exit"); }
// Called when a new tuple is available public void Execute(SCPTuple tuple) { // Get the word from the tuple string word = tuple.GetString(0); // Do we already have an entry for the word in the dictionary? // If no, create one with a count of 0 int count = counts.ContainsKey(word) ? counts[word] : 0; // Increment the count count++; // Update the count in the dictionary counts[word] = count; // Emit the word and count information this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple> { tuple }, new Values(word, count)); }
public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string word = tuple.GetString(0); // grab the first (and only field) from the tuple // figure out if the word has already been encountered or not int count = counts.ContainsKey(word) ? counts[word] : 0; count++; // update counter counts[word] = count; // update the map // log the running count for the word and emit those two fields into the output stream Context.Logger.Info("Emit: {0}, count: {1}", word, count); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple> { tuple }, new Values(word, count)); Context.Logger.Info("Execute exit"); }
// Called when a new tuple is available public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); // Get the word from the tuple string word = tuple.GetString(0); // Do we already have an entry for the word in the dictionary? // If no, create one with a count of 0 int count = counts.ContainsKey(word) ? counts[word] : 0; // Increment the count count++; // Update the count in the dictionary counts[word] = count; Context.Logger.Info("Emit: {0}, count: {1}", word, count); // Emit the word and count information this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(word, count)); Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { var sensor = tuple.GetString(0); var value = tuple.GetDouble(1); //really add logic here!! if (sensor.Equals("Sensor-A", StringComparison.InvariantCultureIgnoreCase) && value > 10) { Context.Logger.Warn("The sensor {0} throw alarms by {1} value", sensor, value); ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <object>() { sensor }); } this.ctx.Ack(tuple); }
// Called when a new tuple is available public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); // Get the sentance from the tuple string sentence = tuple.GetString(0); // Split at space characters foreach (string word in sentence.Split(' ')) { Context.Logger.Info("Emit: {0}", word); if(word=="cow") { //Emit a true to the cowbell stream this.ctx.Emit("cowbells", new Values("ding")); } //Emit each word to the default stream this.ctx.Emit(new Values(word)); } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { int wordCnt = 0; string fileName = tuple.GetString(0); Context.Logger.Info("PartialCount, Execute(), tuple content: {0}", fileName); using (StreamReader reader = new StreamReader(fileName)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); Context.Logger.Info("read line: {0}", line); foreach (string word in line.Split(' ')) { wordCnt++; } } } Context.Logger.Info("Execute(), wordCnt: {0}", wordCnt); this.ctx.Emit(new Values(wordCnt)); }
public static Sensor GetSensor(this SCPTuple tuple) { try { Sensor sensor = null; if (tuple.Size() == 1) { var content = tuple.GetString(0) .Replace("\"", "'") .Replace("\\", ""); sensor = JsonConvert.DeserializeObject <Sensor>(@content); } return(sensor); } catch (Exception ex) { Context.Logger.Error("JSON Serialization error:{0}", ex.ToString()); return(null); } }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column names</param> public void Execute(SCPTuple tuple) { //get the tuple info string sessionId = tuple.GetString(0); string sessionEvent = tuple.GetString(1); long sessionEventTime = tuple.GetLong(2); //If it's a start event, assume there's nothing to find so just re-emit //NOTE: If messages may arrive out of order, you would need to add logic to //query HBase to see if the end event has previously arrived, //calculate the duration, etc. if (sessionEvent == "START") { //Just re-emit the incoming data, plus 0 for duration, since we declare we send a 0 duration //since we don't know the END event yet. Values emitValues = new Values(tuple.GetValue(0), tuple.GetValue(1), tuple.GetValue(2), 0L); //Is ack enabled? if (enableAck) { //Emit the values, anchored to the incoming tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple>() { tuple }, emitValues); //Ack the incoming tuple this.context.Ack(tuple); } else { //No ack enabled? Fire and forget. this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } if (sessionEvent == "END") { //Use filters FilterList filters = new FilterList(FilterList.Operator.MustPassAll); //Filter on the row by sessionID RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.Equal, new BinaryComparator(TypeHelper.ToBytes(sessionId))); filters.AddFilter(rowFilter); //Filter on the event column for the START event SingleColumnValueFilter valueFilter = new SingleColumnValueFilter( Encoding.UTF8.GetBytes("cf"), Encoding.UTF8.GetBytes("event"), CompareFilter.CompareOp.Equal, Encoding.UTF8.GetBytes("START")); filters.AddFilter(valueFilter); //Create scanner settings using the filters var scannerSettings = new Scanner() { filter = filters.ToEncodedString() }; //Get the scanner var scanner = HBaseClusterClient.CreateScanner(HBaseTableName, scannerSettings); CellSet readSet = null; while ((readSet = HBaseClusterClient.ScannerGetNext(scanner)) != null) { //In theory we should only find one row foreach (var row in readSet.rows) { //Pull back just the event column var rowState = row.values.Where(v => Encoding.UTF8.GetString(v.column) == "cf:event") .Select(v => Encoding.UTF8.GetString(v.data)).ToArray()[0]; //Is it a START event as expected? if (rowState == "START") { //Get the start time var startTime = TypeHelper.FromUnixTime( row.values.Where(v => Encoding.UTF8.GetString(v.column) == "cf:time") .Select(v => BitConverter.ToInt64(v.data, 0)).ToArray()[0]); //Get the difference between start and end DateTime endTime = TypeHelper.FromUnixTime(sessionEventTime); TimeSpan duration = endTime.Subtract(startTime); //Emit the tuple, with the duration between start/end. Values emitValues = new Values(sessionId, sessionEvent, sessionEventTime, duration.Ticks); //If ack is enabled if (enableAck) { //Emit the values, anchored to the incoming tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple>() { tuple }, emitValues); //Ack the incoming tuple this.context.Ack(tuple); } else { //No ack enabled? Fire and forget. this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } else { //Since this is a simple example, do nothing. //In a real solution, you'd have to figure out what to do //when receiving an END before a START. } } } } }
public void Execute(SCPTuple tuple) { string cowBell = tuple.GetString(0); this.ctx.Emit(new Values(cowBell)); }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column names</param> public void Execute(SCPTuple tuple) { //get the tuple info string sessionId = tuple.GetString(0); string sessionEvent = tuple.GetString(1); long sessionEventTime = tuple.GetLong(2); //If it's a start event, assume there's nothing to find so just re-emit //NOTE: If messages may arrive out of order, you would need to add logic to //query HBase to see if the end event has previously arrived, //calculate the duration, etc. if (sessionEvent == "START") { //Just re-emit the incoming data, plus 0 for duration, since we declare we send a 0 duration //since we don't know the END event yet. Values emitValues = new Values(tuple.GetValue(0), tuple.GetValue(1), tuple.GetValue(2), 0L); //Is ack enabled? if (enableAck) { //Emit the values, anchored to the incoming tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple>() { tuple }, emitValues); //Ack the incoming tuple this.context.Ack(tuple); } else { //No ack enabled? Fire and forget. this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } if (sessionEvent == "END") { //Use filters FilterList filters = new FilterList(FilterList.Operator.MustPassAll); //Filter on the row by sessionID RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.Equal, new BinaryComparator(TypeHelper.ToBytes(sessionId))); filters.AddFilter(rowFilter); //Filter on the event column for the START event SingleColumnValueFilter valueFilter = new SingleColumnValueFilter( Encoding.UTF8.GetBytes("cf"), Encoding.UTF8.GetBytes("event"), CompareFilter.CompareOp.Equal, Encoding.UTF8.GetBytes("START")); filters.AddFilter(valueFilter); //Create scanner settings using the filters var scannerSettings = new Scanner() { filter = filters.ToEncodedString() }; //Get the scanner var scanner = HBaseClusterClient.CreateScanner(HBaseTableName, scannerSettings); CellSet readSet = null; while ((readSet = HBaseClusterClient.ScannerGetNext(scanner)) != null) { //In theory we should only find one row foreach (var row in readSet.rows) { //Pull back just the event column var rowState = row.values.Where(v => Encoding.UTF8.GetString(v.column) == "cf:event") .Select(v => Encoding.UTF8.GetString(v.data)).ToArray()[0]; //Is it a START event as expected? if (rowState == "START") { //Get the start time var startTime = TypeHelper.FromUnixTime( row.values.Where(v => Encoding.UTF8.GetString(v.column) == "cf:time") .Select(v => BitConverter.ToInt64(v.data,0)).ToArray()[0]); //Get the difference between start and end DateTime endTime = TypeHelper.FromUnixTime(sessionEventTime); TimeSpan duration = endTime.Subtract(startTime); //Emit the tuple, with the duration between start/end. Values emitValues = new Values(sessionId, sessionEvent, sessionEventTime, duration.Ticks); //If ack is enabled if (enableAck) { //Emit the values, anchored to the incoming tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple>() { tuple }, emitValues); //Ack the incoming tuple this.context.Ack(tuple); } else { //No ack enabled? Fire and forget. this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } else { //Since this is a simple example, do nothing. //In a real solution, you'd have to figure out what to do //when receiving an END before a START. } } } } }
public static Sensor GetSensor(this SCPTuple tuple) { return(JsonConvert.DeserializeObject <Sensor>( tuple.GetString(0))); }
/// <summary> /// The execute method for tuple received /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { try { var task = eventHubSender.SendAsync(new EventData(Encoding.UTF8.GetBytes(tuple.GetString(0)))); if (ackEnabled) { tasks.Add(task); this.context.Ack(tuple); if (tasks.Count >= 100) { Context.Logger.Info("Total tasks in waiting = {0}", tasks.Count); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Context.Logger.Info("All waiting tasks completed successfully!", tasks.Count); } } global_emit_count++; if (global_emit_count % 5000 == 0) { Context.Logger.Info("Total events sent to EventHub = {0} ({1} events/sec)", global_emit_count, global_emit_count / globalStopwatch.Elapsed.TotalSeconds); } } catch (Exception ex) { Context.Logger.Error("Failed to send tuples. Last Id = {0}, Value = {1}. Tasks = {2}", tuple.GetTupleId(), tuple.GetString(0), tasks.Count); Context.Logger.Error("Error Details: {0}", ex.ToString()); if (ackEnabled) { this.context.Fail(tuple); } global_error_count++; if (global_error_count > 10) { Context.Logger.Error("High error count: {0}", global_error_count); throw; } if (eventHubSender.IsClosed) { Context.Logger.Warn("EventHubSender is closed, re-intializing..."); InitializeEventHub(); } } }
/// <summary> /// The execute method for tuple received /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { try { var task = eventHubSender.SendAsync(new EventData(Encoding.UTF8.GetBytes(tuple.GetString(0)))); if (ackEnabled) { tasks.Add(task); this.context.Ack(tuple); if (tasks.Count >= 100) { Context.Logger.Info("Total tasks in waiting = {0}", tasks.Count); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Context.Logger.Info("All waiting tasks completed successfully!", tasks.Count); } } global_emit_count++; if (global_emit_count % 5000 == 0) { Context.Logger.Info("Total events sent to EventHub = {0} ({1} events/sec)", global_emit_count, global_emit_count / globalStopwatch.Elapsed.TotalSeconds); } } catch (Exception ex) { Context.Logger.Error("Failed to send tuples. Last Id = {0}, Value = {1}. Tasks = {2}", tuple.GetTupleId(), tuple.GetString(0), tasks.Count); Context.Logger.Error("Error Details: {0}", ex.ToString()); if (ackEnabled) { this.context.Fail(tuple); } global_error_count++; if (global_error_count > 10) { Context.Logger.Error("High error count: {0}", global_error_count); throw; } } }