We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
tagger analyzer not functiong properly 
**Describe the bug**
After upgrade TimeSketch to version: 20210602 the tagger analyzer is not functioning with custom tags

**To Reproduce**
Steps to reproduce the behavior:
1. Import plaso file with evtx data 
2. Add the following tagging rule to tags.yaml
```yaml
logon_tagger:  
  query_string: 'data_type: "windows:evtx:record" AND source_name: "Microsoft-Windows-Security-Auditing" AND event_identifier: 4688'
  tags: ['logon']
  save_search: true
  search_name: 'logon'
```
3. run tagger analyzer
4. See error

**Expected behavior**
The tagger analyzer to run correctly as in previous versions.

**Desktop (please complete the following information):**
-OS:Ubuntu 20.04.2 LTS
-Browser : Firefox
-Version: 86.0

**Additional context**
The following exception is thrown once the tagger analyzer is ran:
```
Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/interface.py", line 995, in run_wrapper result = self.run() File "/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/tagger.py", line 48, in run tag_result = self.tagger(name, tag_config) File "/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/tagger.py", line 100, in tagger if expression: UnboundLocalError: local variable 'expression' referenced before assignment
``` 


--- 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/tagger.py`
Content:
```
1 """Analyzer plugin for tagging."""
2 import logging
3 
4 from timesketch.lib import emojis
5 from timesketch.lib.analyzers import interface
6 from timesketch.lib.analyzers import manager
7 from timesketch.lib.analyzers import utils
8 
9 
10 logger = logging.getLogger('timesketch.analyzers.tagger')
11 
12 
13 class TaggerSketchPlugin(interface.BaseAnalyzer):
14     """Analyzer for tagging events."""
15 
16     NAME = 'tagger'
17     DISPLAY_NAME = 'Tagger'
18     DESCRIPTION = 'Tag events based on pre-defined rules'
19 
20     CONFIG_FILE = 'tags.yaml'
21 
22     def __init__(self, index_name, sketch_id, timeline_id=None, config=None):
23         """Initialize The Sketch Analyzer.
24 
25         Args:
26             index_name: Elasticsearch index name
27             sketch_id: Sketch ID
28             timeline_id: The ID of the timeline.
29             config: Optional dict that contains the configuration for the
30                 analyzer. If not provided, the default YAML file will be used.
31         """
32         self.index_name = index_name
33         self._config = config
34         super().__init__(index_name, sketch_id, timeline_id=timeline_id)
35 
36     def run(self):
37         """Entry point for the analyzer.
38 
39         Returns:
40             String with summary of the analyzer result.
41         """
42         config = self._config or interface.get_yaml_config(self.CONFIG_FILE)
43         if not config:
44             return 'Unable to parse the config file.'
45 
46         tag_results = []
47         for name, tag_config in iter(config.items()):
48             tag_result = self.tagger(name, tag_config)
49             if tag_result and not tag_result.startswith('0 events tagged'):
50                 tag_results.append(tag_result)
51 
52         if tag_results:
53             return ', '.join(tag_results)
54         return 'No tags applied'
55 
56     def tagger(self, name, config):
57         """Tag and add emojis to events.
58 
59         Args:
60             name: String with the name describing what will be tagged.
61             config: A dict that contains the configuration See data/tags.yaml
62                 for fields and documentation of what needs to be defined.
63 
64         Returns:
65             String with summary of the analyzer result.
66         """
67         query = config.get('query_string')
68         query_dsl = config.get('query_dsl')
69         save_search = config.get('save_search', False)
70         # For legacy reasons to support both save_search and
71         # create_view parameters.
72         if not save_search:
73             save_search = config.get('create_view', False)
74 
75         search_name = config.get('search_name', None)
76         # For legacy reasons to support both search_name and view_name.
77         if search_name is None:
78             search_name = config.get('view_name', name)
79 
80         tags = config.get('tags', [])
81         emoji_names = config.get('emojis', [])
82         emojis_to_add = [emojis.get_emoji(x) for x in emoji_names]
83 
84         expression_string = config.get('regular_expression', '')
85         attributes = None
86         if expression_string:
87             expression = utils.compile_regular_expression(
88                 expression_string=expression_string,
89                 expression_flags=config.get('re_flags'))
90 
91             attribute = config.get('re_attribute')
92             if attribute:
93                 attributes = [attribute]
94 
95         event_counter = 0
96         events = self.event_stream(
97             query_string=query, query_dsl=query_dsl, return_fields=attributes)
98 
99         for event in events:
100             if expression:
101                 value = event.source.get(attributes[0])
102                 if value:
103                     result = expression.findall(value)
104                     if not result:
105                         # Skip counting this tag since the regular expression
106                         # didn't find anything.
107                         continue
108 
109             event_counter += 1
110             event.add_tags(tags)
111             event.add_emojis(emojis_to_add)
112 
113             # Commit the event to the datastore.
114             event.commit()
115 
116         if save_search and event_counter:
117             self.sketch.add_view(
118                 search_name, self.NAME, query_string=query, query_dsl=query_dsl)
119 
120         return '{0:d} events tagged for [{1:s}]'.format(event_counter, name)
121 
122 
123 manager.AnalysisManager.register_analyzer(TaggerSketchPlugin)
124
```
--- 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()

```

diff --git a/timesketch/lib/analyzers/tagger.py b/timesketch/lib/analyzers/tagger.py
--- a/timesketch/lib/analyzers/tagger.py
+++ b/timesketch/lib/analyzers/tagger.py
@@ -83,6 +83,7 @@
 
         expression_string = config.get('regular_expression', '')
         attributes = None
+        expression = None
         if expression_string:
             expression = utils.compile_regular_expression(
                 expression_string=expression_string,

{"golden_diff": "diff --git a/timesketch/lib/analyzers/tagger.py b/timesketch/lib/analyzers/tagger.py\n--- a/timesketch/lib/analyzers/tagger.py\n+++ b/timesketch/lib/analyzers/tagger.py\n@@ -83,6 +83,7 @@\n \n         expression_string = config.get('regular_expression', '')\n         attributes = None\n+        expression = None\n         if expression_string:\n             expression = utils.compile_regular_expression(\n                 expression_string=expression_string,\n", "issue": "tagger analyzer not functiong properly \n**Describe the bug**\r\nAfter upgrade TimeSketch to version: 20210602 the tagger analyzer is not functioning with custom tags\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Import plaso file with evtx data \r\n2. Add the following tagging rule to tags.yaml\r\n```yaml\r\nlogon_tagger:  \r\n  query_string: 'data_type: \"windows:evtx:record\" AND source_name: \"Microsoft-Windows-Security-Auditing\" AND event_identifier: 4688'\r\n  tags: ['logon']\r\n  save_search: true\r\n  search_name: 'logon'\r\n```\r\n3. run tagger analyzer\r\n4. See error\r\n\r\n**Expected behavior**\r\nThe tagger analyzer to run correctly as in previous versions.\r\n\r\n**Desktop (please complete the following information):**\r\n-OS:Ubuntu 20.04.2 LTS\r\n-Browser : Firefox\r\n-Version: 86.0\r\n\r\n**Additional context**\r\nThe following exception is thrown once the tagger analyzer is ran:\r\n```\r\nTraceback (most recent call last): File \"/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/interface.py\", line 995, in run_wrapper result = self.run() File \"/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/tagger.py\", line 48, in run tag_result = self.tagger(name, tag_config) File \"/usr/local/lib/python3.8/dist-packages/timesketch/lib/analyzers/tagger.py\", line 100, in tagger if expression: UnboundLocalError: local variable 'expression' referenced before assignment\r\n``` \r\n\n", "before_files": [{"content": "\"\"\"Analyzer plugin for tagging.\"\"\"\nimport logging\n\nfrom timesketch.lib import emojis\nfrom timesketch.lib.analyzers import interface\nfrom timesketch.lib.analyzers import manager\nfrom timesketch.lib.analyzers import utils\n\n\nlogger = logging.getLogger('timesketch.analyzers.tagger')\n\n\nclass TaggerSketchPlugin(interface.BaseAnalyzer):\n    \"\"\"Analyzer for tagging events.\"\"\"\n\n    NAME = 'tagger'\n    DISPLAY_NAME = 'Tagger'\n    DESCRIPTION = 'Tag events based on pre-defined rules'\n\n    CONFIG_FILE = 'tags.yaml'\n\n    def __init__(self, index_name, sketch_id, timeline_id=None, config=None):\n        \"\"\"Initialize The Sketch Analyzer.\n\n        Args:\n            index_name: Elasticsearch index name\n            sketch_id: Sketch ID\n            timeline_id: The ID of the timeline.\n            config: Optional dict that contains the configuration for the\n                analyzer. If not provided, the default YAML file will be used.\n        \"\"\"\n        self.index_name = index_name\n        self._config = config\n        super().__init__(index_name, sketch_id, timeline_id=timeline_id)\n\n    def run(self):\n        \"\"\"Entry point for the analyzer.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n        config = self._config or interface.get_yaml_config(self.CONFIG_FILE)\n        if not config:\n            return 'Unable to parse the config file.'\n\n        tag_results = []\n        for name, tag_config in iter(config.items()):\n            tag_result = self.tagger(name, tag_config)\n            if tag_result and not tag_result.startswith('0 events tagged'):\n                tag_results.append(tag_result)\n\n        if tag_results:\n            return ', '.join(tag_results)\n        return 'No tags applied'\n\n    def tagger(self, name, config):\n        \"\"\"Tag and add emojis to events.\n\n        Args:\n            name: String with the name describing what will be tagged.\n            config: A dict that contains the configuration See data/tags.yaml\n                for fields and documentation of what needs to be defined.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n        query = config.get('query_string')\n        query_dsl = config.get('query_dsl')\n        save_search = config.get('save_search', False)\n        # For legacy reasons to support both save_search and\n        # create_view parameters.\n        if not save_search:\n            save_search = config.get('create_view', False)\n\n        search_name = config.get('search_name', None)\n        # For legacy reasons to support both search_name and view_name.\n        if search_name is None:\n            search_name = config.get('view_name', name)\n\n        tags = config.get('tags', [])\n        emoji_names = config.get('emojis', [])\n        emojis_to_add = [emojis.get_emoji(x) for x in emoji_names]\n\n        expression_string = config.get('regular_expression', '')\n        attributes = None\n        if expression_string:\n            expression = utils.compile_regular_expression(\n                expression_string=expression_string,\n                expression_flags=config.get('re_flags'))\n\n            attribute = config.get('re_attribute')\n            if attribute:\n                attributes = [attribute]\n\n        event_counter = 0\n        events = self.event_stream(\n            query_string=query, query_dsl=query_dsl, return_fields=attributes)\n\n        for event in events:\n            if expression:\n                value = event.source.get(attributes[0])\n                if value:\n                    result = expression.findall(value)\n                    if not result:\n                        # Skip counting this tag since the regular expression\n                        # didn't find anything.\n                        continue\n\n            event_counter += 1\n            event.add_tags(tags)\n            event.add_emojis(emojis_to_add)\n\n            # Commit the event to the datastore.\n            event.commit()\n\n        if save_search and event_counter:\n            self.sketch.add_view(\n                search_name, self.NAME, query_string=query, query_dsl=query_dsl)\n\n        return '{0:d} events tagged for [{1:s}]'.format(event_counter, name)\n\n\nmanager.AnalysisManager.register_analyzer(TaggerSketchPlugin)\n", "path": "timesketch/lib/analyzers/tagger.py"}], "after_files": [{"content": "\"\"\"Analyzer plugin for tagging.\"\"\"\nimport logging\n\nfrom timesketch.lib import emojis\nfrom timesketch.lib.analyzers import interface\nfrom timesketch.lib.analyzers import manager\nfrom timesketch.lib.analyzers import utils\n\n\nlogger = logging.getLogger('timesketch.analyzers.tagger')\n\n\nclass TaggerSketchPlugin(interface.BaseAnalyzer):\n    \"\"\"Analyzer for tagging events.\"\"\"\n\n    NAME = 'tagger'\n    DISPLAY_NAME = 'Tagger'\n    DESCRIPTION = 'Tag events based on pre-defined rules'\n\n    CONFIG_FILE = 'tags.yaml'\n\n    def __init__(self, index_name, sketch_id, timeline_id=None, config=None):\n        \"\"\"Initialize The Sketch Analyzer.\n\n        Args:\n            index_name: Elasticsearch index name\n            sketch_id: Sketch ID\n            timeline_id: The ID of the timeline.\n            config: Optional dict that contains the configuration for the\n                analyzer. If not provided, the default YAML file will be used.\n        \"\"\"\n        self.index_name = index_name\n        self._config = config\n        super().__init__(index_name, sketch_id, timeline_id=timeline_id)\n\n    def run(self):\n        \"\"\"Entry point for the analyzer.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n        config = self._config or interface.get_yaml_config(self.CONFIG_FILE)\n        if not config:\n            return 'Unable to parse the config file.'\n\n        tag_results = []\n        for name, tag_config in iter(config.items()):\n            tag_result = self.tagger(name, tag_config)\n            if tag_result and not tag_result.startswith('0 events tagged'):\n                tag_results.append(tag_result)\n\n        if tag_results:\n            return ', '.join(tag_results)\n        return 'No tags applied'\n\n    def tagger(self, name, config):\n        \"\"\"Tag and add emojis to events.\n\n        Args:\n            name: String with the name describing what will be tagged.\n            config: A dict that contains the configuration See data/tags.yaml\n                for fields and documentation of what needs to be defined.\n\n        Returns:\n            String with summary of the analyzer result.\n        \"\"\"\n        query = config.get('query_string')\n        query_dsl = config.get('query_dsl')\n        save_search = config.get('save_search', False)\n        # For legacy reasons to support both save_search and\n        # create_view parameters.\n        if not save_search:\n            save_search = config.get('create_view', False)\n\n        search_name = config.get('search_name', None)\n        # For legacy reasons to support both search_name and view_name.\n        if search_name is None:\n            search_name = config.get('view_name', name)\n\n        tags = config.get('tags', [])\n        emoji_names = config.get('emojis', [])\n        emojis_to_add = [emojis.get_emoji(x) for x in emoji_names]\n\n        expression_string = config.get('regular_expression', '')\n        attributes = None\n        expression = None\n        if expression_string:\n            expression = utils.compile_regular_expression(\n                expression_string=expression_string,\n                expression_flags=config.get('re_flags'))\n\n            attribute = config.get('re_attribute')\n            if attribute:\n                attributes = [attribute]\n\n        event_counter = 0\n        events = self.event_stream(\n            query_string=query, query_dsl=query_dsl, return_fields=attributes)\n\n        for event in events:\n            if expression:\n                value = event.source.get(attributes[0])\n                if value:\n                    result = expression.findall(value)\n                    if not result:\n                        # Skip counting this tag since the regular expression\n                        # didn't find anything.\n                        continue\n\n            event_counter += 1\n            event.add_tags(tags)\n            event.add_emojis(emojis_to_add)\n\n            # Commit the event to the datastore.\n            event.commit()\n\n        if save_search and event_counter:\n            self.sketch.add_view(\n                search_name, self.NAME, query_string=query, query_dsl=query_dsl)\n\n        return '{0:d} events tagged for [{1:s}]'.format(event_counter, name)\n\n\nmanager.AnalysisManager.register_analyzer(TaggerSketchPlugin)\n", "path": "timesketch/lib/analyzers/tagger.py"}]}