prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Sigma tags as labels / tags for events
  Sigma rules do come with something like:
  
  ```
  tags:
      - attack.initial_access
      - attack.t1190
     ```
  
  It could be useful to apply those tags to events that are found with the Sigma analyzer that does tag / label events. Instead (or in addition) of just the filename, the tags from the Sigma rule could be applied.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `timesketch/lib/analyzers/sigma_tagger.py`
  Content:
  ```
  1 """Index analyzer plugin for sigma."""
  2 from __future__ import unicode_literals
  3 
  4 import logging
  5 import time
  6 import elasticsearch
  7 
  8 from timesketch.lib.analyzers import utils
  9 
  10 from timesketch.lib.analyzers import interface
  11 from timesketch.lib.analyzers import manager
  12 import timesketch.lib.sigma_util as ts_sigma_lib
  13 
  14 
  15 logger = logging.getLogger('timesketch.analyzers.sigma_tagger')
  16 
  17 
  18 class SigmaPlugin(interface.BaseAnalyzer):
  19     """Analyzer for Sigma."""
  20 
  21     NAME = 'sigma'
  22     DISPLAY_NAME = 'Sigma'
  23     DESCRIPTION = 'Run pre-defined Sigma rules and tag matching events'
  24 
  25     def run_sigma_rule(self, query, tag_name):
  26         """Runs a sigma rule and applies the appropriate tags.
  27 
  28         Args:
  29             query: elastic search query for events to tag.
  30             tag_name: tag to apply to matching events.
  31 
  32         Returns:
  33             int: number of events tagged.
  34         """
  35         return_fields = []
  36         tagged_events_counter = 0
  37         events = self.event_stream(
  38             query_string=query, return_fields=return_fields)
  39         for event in events:
  40             event.add_tags(['sigma_{0:s}'.format(tag_name)])
  41             event.commit()
  42             tagged_events_counter += 1
  43         return tagged_events_counter
  44 
  45     def run(self):
  46         """Entry point for the analyzer.
  47 
  48         Returns:
  49             String with summary of the analyzer result.
  50         """
  51 
  52         tags_applied = {}
  53         sigma_rule_counter = 0
  54         sigma_rules = ts_sigma_lib.get_all_sigma_rules()
  55 
  56         if sigma_rules is None:
  57             logger.error('No  Sigma rules found. Check SIGMA_RULES_FOLDERS')
  58 
  59         problem_strings = []
  60         output_strings = []
  61 
  62         for rule in sigma_rules:
  63             tags_applied[rule.get('file_name')] = 0
  64             try:
  65                 sigma_rule_counter += 1
  66                 tagged_events_counter = self.run_sigma_rule(
  67                     rule.get('es_query'), rule.get('file_name'))
  68                 tags_applied[rule.get('file_name')] += tagged_events_counter
  69             except elasticsearch.TransportError as e:
  70                 logger.error(
  71                     'Timeout executing search for {0:s}: '
  72                     '{1!s} waiting for 10 seconds'.format(
  73                         rule.get('file_name'), e), exc_info=True)
  74                 # this is caused by to many ES queries in short time range
  75                 # thus waiting for 10 seconds before sending the next one.
  76                 time.sleep(10)
  77             # This except block is by purpose very broad as one bad rule could
  78             # otherwise stop the whole analyzer run
  79             # it might be an option to write the problematic rules to the output
  80             except: # pylint: disable=bare-except
  81                 logger.error(
  82                     'Problem with rule in file {0:s}: '.format(
  83                         rule.get('file_name')), exc_info=True)
  84                 problem_strings.append('* {0:s}'.format(
  85                     rule.get('file_name')))
  86                 continue
  87 
  88         total_tagged_events = sum(tags_applied.values())
  89         output_strings.append('Applied {0:d} tags'.format(total_tagged_events))
  90         for tag_name, tagged_events_counter in tags_applied.items():
  91             output_strings.append('* {0:s}: {1:d}'.format(
  92                 tag_name, tagged_events_counter))
  93 
  94         if sigma_rule_counter > 0:
  95             view = self.sketch.add_view(
  96                 view_name='Sigma Rule matches', analyzer_name=self.NAME,
  97                 query_string='tag:"sigma*"')
  98             agg_params = {
  99                 'field': 'tag',
  100                 'limit': 20,
  101                 'index': [self.timeline_id],
  102             }
  103             agg_obj = self.sketch.add_aggregation(
  104                 name='Top 20 Sigma tags', agg_name='field_bucket',
  105                 agg_params=agg_params, view_id=view.id, chart_type='hbarchart',
  106                 description='Created by the Sigma analyzer')
  107 
  108             story = self.sketch.add_story('Sigma Rule hits')
  109             story.add_text(
  110                 utils.SIGMA_STORY_HEADER, skip_if_exists=True)
  111 
  112             story.add_text(
  113                 '## Sigma Analyzer.\n\nThe Sigma '
  114                 'analyzer takes Events and matches them with Sigma rules.'
  115                 'In this timeline the analyzer discovered {0:d} '
  116                 'Sigma tags.\n\nThis is a summary of '
  117                 'it\'s findings.'.format(sigma_rule_counter))
  118             story.add_text(
  119                 'The top 20 most commonly discovered tags were:')
  120             story.add_aggregation(agg_obj)
  121             story.add_text(
  122                 'And an overview of all the discovered search terms:')
  123             story.add_view(view)
  124 
  125         output_strings.append('Problematic rules:')
  126         output_strings.extend(problem_strings)
  127 
  128         return '\n'.join(output_strings)
  129 
  130 
  131 class RulesSigmaPlugin(SigmaPlugin):
  132     """Sigma plugin to run rules."""
  133 
  134     NAME = 'sigma'
  135 
  136 manager.AnalysisManager.register_analyzer(RulesSigmaPlugin)
  137
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/timesketch/lib/analyzers/sigma_tagger.py b/timesketch/lib/analyzers/sigma_tagger.py
  --- a/timesketch/lib/analyzers/sigma_tagger.py
  +++ b/timesketch/lib/analyzers/sigma_tagger.py
  @@ -22,12 +22,13 @@
       DISPLAY_NAME = 'Sigma'
       DESCRIPTION = 'Run pre-defined Sigma rules and tag matching events'
   
  -    def run_sigma_rule(self, query, tag_name):
  +    def run_sigma_rule(self, query, rule_name, tag_list = None):
           """Runs a sigma rule and applies the appropriate tags.
   
           Args:
               query: elastic search query for events to tag.
  -            tag_name: tag to apply to matching events.
  +            rule_name: rule_name to apply to matching events.
  +            tag_list: a list of additional tags to be added to the event(s)
   
           Returns:
               int: number of events tagged.
  @@ -37,7 +38,8 @@
           events = self.event_stream(
               query_string=query, return_fields=return_fields)
           for event in events:
  -            event.add_tags(['sigma_{0:s}'.format(tag_name)])
  +            event.add_tags(['sigma_{0:s}'.format(rule_name)])
  +            event.add_tags(tag_list)
               event.commit()
               tagged_events_counter += 1
           return tagged_events_counter
  @@ -64,7 +66,8 @@
               try:
                   sigma_rule_counter += 1
                   tagged_events_counter = self.run_sigma_rule(
  -                    rule.get('es_query'), rule.get('file_name'))
  +                    rule.get('es_query'), rule.get('file_name'),
  +                    tag_list=rule.get('tags'))
                   tags_applied[rule.get('file_name')] += tagged_events_counter
               except elasticsearch.TransportError as e:
                   logger.error(
  
verification_info: {"golden_diff": "diff --git a/timesketch/lib/analyzers/sigma_tagger.py b/timesketch/lib/analyzers/sigma_tagger.py\n--- a/timesketch/lib/analyzers/sigma_tagger.py\n+++ b/timesketch/lib/analyzers/sigma_tagger.py\n@@ -22,12 +22,13 @@\n     DISPLAY_NAME = 'Sigma'\n     DESCRIPTION = 'Run pre-defined Sigma rules and tag matching events'\n \n-    def run_sigma_rule(self, query, tag_name):\n+    def run_sigma_rule(self, query, rule_name, tag_list = None):\n         \"\"\"Runs a sigma rule and applies the appropriate tags.\n \n         Args:\n             query: elastic search query for events to tag.\n-            tag_name: tag to apply to matching events.\n+            rule_name: rule_name to apply to matching events.\n+            tag_list: a list of additional tags to be added to the event(s)\n \n         Returns:\n             int: number of events tagged.\n@@ -37,7 +38,8 @@\n         events = self.event_stream(\n             query_string=query, return_fields=return_fields)\n         for event in events:\n-            event.add_tags(['sigma_{0:s}'.format(tag_name)])\n+            event.add_tags(['sigma_{0:s}'.format(rule_name)])\n+            event.add_tags(tag_list)\n             event.commit()\n             tagged_events_counter += 1\n         return tagged_events_counter\n@@ -64,7 +66,8 @@\n             try:\n                 sigma_rule_counter += 1\n                 tagged_events_counter = self.run_sigma_rule(\n-                    rule.get('es_query'), rule.get('file_name'))\n+                    rule.get('es_query'), rule.get('file_name'),\n+                    tag_list=rule.get('tags'))\n                 tags_applied[rule.get('file_name')] += tagged_events_counter\n             except elasticsearch.TransportError as e:\n                 logger.error(\n", "issue": "Sigma tags as labels / tags for events\nSigma rules do come with something like:\r\n\r\n```\r\ntags:\r\n    - attack.initial_access\r\n    - attack.t1190\r\n   ```\r\n\r\nIt could be useful to apply those tags to events that are found with the Sigma analyzer that does tag / label events. Instead (or in addition) of just the filename, the tags from the Sigma rule could be applied.\n", "before_files": [{"content": "\"\"\"Index analyzer plugin for sigma.\"\"\"\nfrom __future__ import unicode_literals\n\nimport logging\nimport time\nimport elasticsearch\n\nfrom timesketch.lib.analyzers import utils\n\nfrom timesketch.lib.analyzers import interface\nfrom timesketch.lib.analyzers import manager\nimport timesketch.lib.sigma_util as ts_sigma_lib\n\n\nlogger = logging.getLogger('timesketch.analyzers.sigma_tagger')\n\n\nclass SigmaPlugin(interface.BaseAnalyzer):\n    \"\"\"Analyzer for Sigma.\"\"\"\n\n    NAME = 'sigma'\n    DISPLAY_NAME = 'Sigma'\n    DESCRIPTION = 'Run pre-defined Sigma rules and tag matching events'\n\n    def run_sigma_rule(self, query, tag_name):\n        \"\"\"Runs a sigma rule and applies the appropriate tags.\n\n        Args:\n            query: elastic search query for events to tag.\n            tag_name: tag to apply to matching events.\n\n        Returns:\n            int: number of events tagged.\n        \"\"\"\n        return_fields = []\n        tagged_events_counter = 0\n        events = self.event_stream(\n            query_string=query, return_fields=return_fields)\n        for event in events:\n            event.add_tags(['sigma_{0:s}'.format(tag_name)])\n            event.commit()\n            tagged_events_counter += 1\n        return tagged_events_counter\n\n    def run(self):\n        \"\"\"Entry point for the analyzer.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n\n        tags_applied = {}\n        sigma_rule_counter = 0\n        sigma_rules = ts_sigma_lib.get_all_sigma_rules()\n\n        if sigma_rules is None:\n            logger.error('No  Sigma rules found. Check SIGMA_RULES_FOLDERS')\n\n        problem_strings = []\n        output_strings = []\n\n        for rule in sigma_rules:\n            tags_applied[rule.get('file_name')] = 0\n            try:\n                sigma_rule_counter += 1\n                tagged_events_counter = self.run_sigma_rule(\n                    rule.get('es_query'), rule.get('file_name'))\n                tags_applied[rule.get('file_name')] += tagged_events_counter\n            except elasticsearch.TransportError as e:\n                logger.error(\n                    'Timeout executing search for {0:s}: '\n                    '{1!s} waiting for 10 seconds'.format(\n                        rule.get('file_name'), e), exc_info=True)\n                # this is caused by to many ES queries in short time range\n                # thus waiting for 10 seconds before sending the next one.\n                time.sleep(10)\n            # This except block is by purpose very broad as one bad rule could\n            # otherwise stop the whole analyzer run\n            # it might be an option to write the problematic rules to the output\n            except: # pylint: disable=bare-except\n                logger.error(\n                    'Problem with rule in file {0:s}: '.format(\n                        rule.get('file_name')), exc_info=True)\n                problem_strings.append('* {0:s}'.format(\n                    rule.get('file_name')))\n                continue\n\n        total_tagged_events = sum(tags_applied.values())\n        output_strings.append('Applied {0:d} tags'.format(total_tagged_events))\n        for tag_name, tagged_events_counter in tags_applied.items():\n            output_strings.append('* {0:s}: {1:d}'.format(\n                tag_name, tagged_events_counter))\n\n        if sigma_rule_counter > 0:\n            view = self.sketch.add_view(\n                view_name='Sigma Rule matches', analyzer_name=self.NAME,\n                query_string='tag:\"sigma*\"')\n            agg_params = {\n                'field': 'tag',\n                'limit': 20,\n                'index': [self.timeline_id],\n            }\n            agg_obj = self.sketch.add_aggregation(\n                name='Top 20 Sigma tags', agg_name='field_bucket',\n                agg_params=agg_params, view_id=view.id, chart_type='hbarchart',\n                description='Created by the Sigma analyzer')\n\n            story = self.sketch.add_story('Sigma Rule hits')\n            story.add_text(\n                utils.SIGMA_STORY_HEADER, skip_if_exists=True)\n\n            story.add_text(\n                '## Sigma Analyzer.\\n\\nThe Sigma '\n                'analyzer takes Events and matches them with Sigma rules.'\n                'In this timeline the analyzer discovered {0:d} '\n                'Sigma tags.\\n\\nThis is a summary of '\n                'it\\'s findings.'.format(sigma_rule_counter))\n            story.add_text(\n                'The top 20 most commonly discovered tags were:')\n            story.add_aggregation(agg_obj)\n            story.add_text(\n                'And an overview of all the discovered search terms:')\n            story.add_view(view)\n\n        output_strings.append('Problematic rules:')\n        output_strings.extend(problem_strings)\n\n        return '\\n'.join(output_strings)\n\n\nclass RulesSigmaPlugin(SigmaPlugin):\n    \"\"\"Sigma plugin to run rules.\"\"\"\n\n    NAME = 'sigma'\n\nmanager.AnalysisManager.register_analyzer(RulesSigmaPlugin)\n", "path": "timesketch/lib/analyzers/sigma_tagger.py"}], "after_files": [{"content": "\"\"\"Index analyzer plugin for sigma.\"\"\"\nfrom __future__ import unicode_literals\n\nimport logging\nimport time\nimport elasticsearch\n\nfrom timesketch.lib.analyzers import utils\n\nfrom timesketch.lib.analyzers import interface\nfrom timesketch.lib.analyzers import manager\nimport timesketch.lib.sigma_util as ts_sigma_lib\n\n\nlogger = logging.getLogger('timesketch.analyzers.sigma_tagger')\n\n\nclass SigmaPlugin(interface.BaseAnalyzer):\n    \"\"\"Analyzer for Sigma.\"\"\"\n\n    NAME = 'sigma'\n    DISPLAY_NAME = 'Sigma'\n    DESCRIPTION = 'Run pre-defined Sigma rules and tag matching events'\n\n    def run_sigma_rule(self, query, rule_name, tag_list = None):\n        \"\"\"Runs a sigma rule and applies the appropriate tags.\n\n        Args:\n            query: elastic search query for events to tag.\n            rule_name: rule_name to apply to matching events.\n            tag_list: a list of additional tags to be added to the event(s)\n\n        Returns:\n            int: number of events tagged.\n        \"\"\"\n        return_fields = []\n        tagged_events_counter = 0\n        events = self.event_stream(\n            query_string=query, return_fields=return_fields)\n        for event in events:\n            event.add_tags(['sigma_{0:s}'.format(rule_name)])\n            event.add_tags(tag_list)\n            event.commit()\n            tagged_events_counter += 1\n        return tagged_events_counter\n\n    def run(self):\n        \"\"\"Entry point for the analyzer.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n\n        tags_applied = {}\n        sigma_rule_counter = 0\n        sigma_rules = ts_sigma_lib.get_all_sigma_rules()\n\n        if sigma_rules is None:\n            logger.error('No  Sigma rules found. Check SIGMA_RULES_FOLDERS')\n\n        problem_strings = []\n        output_strings = []\n\n        for rule in sigma_rules:\n            tags_applied[rule.get('file_name')] = 0\n            try:\n                sigma_rule_counter += 1\n                tagged_events_counter = self.run_sigma_rule(\n                    rule.get('es_query'), rule.get('file_name'),\n                    tag_list=rule.get('tags'))\n                tags_applied[rule.get('file_name')] += tagged_events_counter\n            except elasticsearch.TransportError as e:\n                logger.error(\n                    'Timeout executing search for {0:s}: '\n                    '{1!s} waiting for 10 seconds'.format(\n                        rule.get('file_name'), e), exc_info=True)\n                # this is caused by to many ES queries in short time range\n                # thus waiting for 10 seconds before sending the next one.\n                time.sleep(10)\n            # This except block is by purpose very broad as one bad rule could\n            # otherwise stop the whole analyzer run\n            # it might be an option to write the problematic rules to the output\n            except: # pylint: disable=bare-except\n                logger.error(\n                    'Problem with rule in file {0:s}: '.format(\n                        rule.get('file_name')), exc_info=True)\n                problem_strings.append('* {0:s}'.format(\n                    rule.get('file_name')))\n                continue\n\n        total_tagged_events = sum(tags_applied.values())\n        output_strings.append('Applied {0:d} tags'.format(total_tagged_events))\n        for tag_name, tagged_events_counter in tags_applied.items():\n            output_strings.append('* {0:s}: {1:d}'.format(\n                tag_name, tagged_events_counter))\n\n        if sigma_rule_counter > 0:\n            view = self.sketch.add_view(\n                view_name='Sigma Rule matches', analyzer_name=self.NAME,\n                query_string='tag:\"sigma*\"')\n            agg_params = {\n                'field': 'tag',\n                'limit': 20,\n                'index': [self.timeline_id],\n            }\n            agg_obj = self.sketch.add_aggregation(\n                name='Top 20 Sigma tags', agg_name='field_bucket',\n                agg_params=agg_params, view_id=view.id, chart_type='hbarchart',\n                description='Created by the Sigma analyzer')\n\n            story = self.sketch.add_story('Sigma Rule hits')\n            story.add_text(\n                utils.SIGMA_STORY_HEADER, skip_if_exists=True)\n\n            story.add_text(\n                '## Sigma Analyzer.\\n\\nThe Sigma '\n                'analyzer takes Events and matches them with Sigma rules.'\n                'In this timeline the analyzer discovered {0:d} '\n                'Sigma tags.\\n\\nThis is a summary of '\n                'it\\'s findings.'.format(sigma_rule_counter))\n            story.add_text(\n                'The top 20 most commonly discovered tags were:')\n            story.add_aggregation(agg_obj)\n            story.add_text(\n                'And an overview of all the discovered search terms:')\n            story.add_view(view)\n\n        output_strings.append('Problematic rules:')\n        output_strings.extend(problem_strings)\n\n        return '\\n'.join(output_strings)\n\n\nclass RulesSigmaPlugin(SigmaPlugin):\n    \"\"\"Sigma plugin to run rules.\"\"\"\n\n    NAME = 'sigma'\n\nmanager.AnalysisManager.register_analyzer(RulesSigmaPlugin)\n", "path": "timesketch/lib/analyzers/sigma_tagger.py"}]}