We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Log important events into a file
solaar does log warnings in case of failure, e.g.
```
12:25:57,373  WARNING [MainThread] logitech_receiver.diversion: cannot create uinput device: "/dev/uinput" cannot be opened for writing
```
but these warnings appear to be only visible on the console, on stdout. To see these warnings, (an auto-started) solaar needs to be stopped (pkill solaar) and the launched from the console. This enables users to see future log entries.

It would be nicer to have solaar (also) log important events into the journald log, enabling users to inspect the logs for any solaar events that failed ... looking _back_.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/solaar/gtk.py`
Content:
```
1 #!/usr/bin/env python3
2 # -*- python-mode -*-
3 # -*- coding: UTF-8 -*-
4 
5 ## Copyright (C) 2012-2013  Daniel Pavel
6 ##
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation; either version 2 of the License, or
10 ## (at your option) any later version.
11 ##
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ## GNU General Public License for more details.
16 ##
17 ## You should have received a copy of the GNU General Public License along
18 ## with this program; if not, write to the Free Software Foundation, Inc.,
19 ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 
21 import importlib
22 import os.path
23 
24 from logging import INFO as _INFO
25 from logging import WARNING as _WARNING
26 from logging import getLogger
27 
28 import solaar.cli as _cli
29 import solaar.i18n as _i18n
30 
31 from solaar import NAME, __version__
32 
33 _log = getLogger(__name__)
34 del getLogger
35 
36 #
37 #
38 #
39 
40 
41 def _require(module, os_package, gi=None, gi_package=None, gi_version=None):
42     try:
43         if gi is not None:
44             gi.require_version(gi_package, gi_version)
45         return importlib.import_module(module)
46     except (ImportError, ValueError):
47         import sys
48         sys.exit('%s: missing required system package %s' % (NAME, os_package))
49 
50 
51 battery_icons_style = 'regular'
52 
53 
54 def _parse_arguments():
55     import argparse
56     arg_parser = argparse.ArgumentParser(
57         prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'
58     )
59     arg_parser.add_argument(
60         '-d',
61         '--debug',
62         action='count',
63         default=0,
64         help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'
65     )
66     arg_parser.add_argument(
67         '-D',
68         '--hidraw',
69         action='store',
70         dest='hidraw_path',
71         metavar='PATH',
72         help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'
73     )
74     arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')
75     arg_parser.add_argument(
76         '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'
77     )
78     arg_parser.add_argument(
79         '-b',
80         '--battery-icons',
81         choices=('regular', 'symbolic', 'solaar'),
82         help='prefer regular battery / symbolic battery / solaar icons'
83     )
84     arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')
85     arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)
86     arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')
87     arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')
88 
89     args = arg_parser.parse_args()
90 
91     if args.help_actions:
92         _cli.print_help()
93         return
94 
95     if args.window is None:
96         args.window = 'show'  # default behaviour is to show main window
97 
98     global battery_icons_style
99     battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'
100     global tray_icon_size
101     tray_icon_size = args.tray_icon_size
102 
103     import logging
104     if args.debug > 0:
105         log_level = logging.ERROR - 10 * args.debug
106         log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'
107         logging.basicConfig(level=max(log_level, logging.DEBUG), format=log_format, datefmt='%H:%M:%S')
108     else:
109         logging.root.addHandler(logging.NullHandler())
110         logging.root.setLevel(logging.ERROR)
111 
112     if not args.action:
113         if logging.root.isEnabledFor(logging.INFO):
114             logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)
115 
116     return args
117 
118 
119 # On first SIGINT, dump threads to stderr; on second, exit
120 def _handlesigint(signal, stack):
121     import signal
122     import sys
123     import faulthandler
124     signal.signal(signal.SIGINT, signal.SIG_DFL)
125 
126     if _log.isEnabledFor(_INFO):
127         faulthandler.dump_traceback()
128 
129     sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))
130 
131 
132 def main():
133     _require('pyudev', 'python3-pyudev')
134 
135     # handle ^C in console
136     import signal
137     signal.signal(signal.SIGINT, signal.SIG_DFL)
138     signal.signal(signal.SIGINT, _handlesigint)
139 
140     args = _parse_arguments()
141     if not args:
142         return
143     if args.action:
144         # if any argument, run comandline and exit
145         return _cli.run(args.action, args.hidraw_path)
146 
147     gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')
148     _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')
149 
150     udev_file = '42-logitech-unify-permissions.rules'
151     if _log.isEnabledFor(_WARNING) \
152        and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \
153        and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \
154        and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):
155         _log.warning('Solaar udev file not found in expected location')
156         _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')
157     try:
158         import solaar.ui as ui
159         import solaar.listener as listener
160         listener.setup_scanner(ui.status_changed, ui.error_dialog)
161 
162         import solaar.upower as _upower
163         if args.restart_on_wake_up:
164             _upower.watch(listener.start_all, listener.stop_all)
165         else:
166             _upower.watch(lambda: listener.ping_all(True))
167 
168         # main UI event loop
169         ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')
170     except Exception:
171         import sys
172         from traceback import format_exc
173         sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))
174 
175 
176 if __name__ == '__main__':
177     main()
178
```
--- 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/lib/solaar/gtk.py b/lib/solaar/gtk.py
--- a/lib/solaar/gtk.py
+++ b/lib/solaar/gtk.py
@@ -19,19 +19,19 @@
 ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 import importlib
+import logging
 import os.path
+import tempfile
 
 from logging import INFO as _INFO
 from logging import WARNING as _WARNING
-from logging import getLogger
 
 import solaar.cli as _cli
 import solaar.i18n as _i18n
 
 from solaar import NAME, __version__
 
-_log = getLogger(__name__)
-del getLogger
+_log = logging.getLogger(__name__)
 
 #
 #
@@ -49,6 +49,7 @@
 
 
 battery_icons_style = 'regular'
+temp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)
 
 
 def _parse_arguments():
@@ -100,17 +101,21 @@
     global tray_icon_size
     tray_icon_size = args.tray_icon_size
 
-    import logging
+    log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'
+    log_level = logging.ERROR - 10 * args.debug
+    logging.getLogger('').setLevel(min(log_level, logging.WARNING))
+    file_handler = logging.StreamHandler(temp)
+    file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))
+    file_handler.setFormatter(logging.Formatter(log_format))
+    logging.getLogger('').addHandler(file_handler)
     if args.debug > 0:
-        log_level = logging.ERROR - 10 * args.debug
-        log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'
-        logging.basicConfig(level=max(log_level, logging.DEBUG), format=log_format, datefmt='%H:%M:%S')
-    else:
-        logging.root.addHandler(logging.NullHandler())
-        logging.root.setLevel(logging.ERROR)
+        stream_handler = logging.StreamHandler()
+        stream_handler.setFormatter(logging.Formatter(log_format))
+        stream_handler.setLevel(log_level)
+        logging.getLogger('').addHandler(stream_handler)
 
     if not args.action:
-        if logging.root.isEnabledFor(logging.INFO):
+        if _log.isEnabledFor(logging.INFO):
             logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)
 
     return args
@@ -172,6 +177,8 @@
         from traceback import format_exc
         sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))
 
+    temp.close()
+
 
 if __name__ == '__main__':
     main()

{"golden_diff": "diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py\n--- a/lib/solaar/gtk.py\n+++ b/lib/solaar/gtk.py\n@@ -19,19 +19,19 @@\n ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n \n import importlib\n+import logging\n import os.path\n+import tempfile\n \n from logging import INFO as _INFO\n from logging import WARNING as _WARNING\n-from logging import getLogger\n \n import solaar.cli as _cli\n import solaar.i18n as _i18n\n \n from solaar import NAME, __version__\n \n-_log = getLogger(__name__)\n-del getLogger\n+_log = logging.getLogger(__name__)\n \n #\n #\n@@ -49,6 +49,7 @@\n \n \n battery_icons_style = 'regular'\n+temp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)\n \n \n def _parse_arguments():\n@@ -100,17 +101,21 @@\n     global tray_icon_size\n     tray_icon_size = args.tray_icon_size\n \n-    import logging\n+    log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n+    log_level = logging.ERROR - 10 * args.debug\n+    logging.getLogger('').setLevel(min(log_level, logging.WARNING))\n+    file_handler = logging.StreamHandler(temp)\n+    file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))\n+    file_handler.setFormatter(logging.Formatter(log_format))\n+    logging.getLogger('').addHandler(file_handler)\n     if args.debug > 0:\n-        log_level = logging.ERROR - 10 * args.debug\n-        log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n-        logging.basicConfig(level=max(log_level, logging.DEBUG), format=log_format, datefmt='%H:%M:%S')\n-    else:\n-        logging.root.addHandler(logging.NullHandler())\n-        logging.root.setLevel(logging.ERROR)\n+        stream_handler = logging.StreamHandler()\n+        stream_handler.setFormatter(logging.Formatter(log_format))\n+        stream_handler.setLevel(log_level)\n+        logging.getLogger('').addHandler(stream_handler)\n \n     if not args.action:\n-        if logging.root.isEnabledFor(logging.INFO):\n+        if _log.isEnabledFor(logging.INFO):\n             logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)\n \n     return args\n@@ -172,6 +177,8 @@\n         from traceback import format_exc\n         sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))\n \n+    temp.close()\n+\n \n if __name__ == '__main__':\n     main()\n", "issue": "Log important events into a file\nsolaar does log warnings in case of failure, e.g.\r\n```\r\n12:25:57,373  WARNING [MainThread] logitech_receiver.diversion: cannot create uinput device: \"/dev/uinput\" cannot be opened for writing\r\n```\r\nbut these warnings appear to be only visible on the console, on stdout. To see these warnings, (an auto-started) solaar needs to be stopped (pkill solaar) and the launched from the console. This enables users to see future log entries.\r\n\r\nIt would be nicer to have solaar (also) log important events into the journald log, enabling users to inspect the logs for any solaar events that failed ... looking _back_.\n", "before_files": [{"content": "#!/usr/bin/env python3\n# -*- python-mode -*-\n# -*- coding: UTF-8 -*-\n\n## Copyright (C) 2012-2013  Daniel Pavel\n##\n## This program is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License along\n## with this program; if not, write to the Free Software Foundation, Inc.,\n## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport importlib\nimport os.path\n\nfrom logging import INFO as _INFO\nfrom logging import WARNING as _WARNING\nfrom logging import getLogger\n\nimport solaar.cli as _cli\nimport solaar.i18n as _i18n\n\nfrom solaar import NAME, __version__\n\n_log = getLogger(__name__)\ndel getLogger\n\n#\n#\n#\n\n\ndef _require(module, os_package, gi=None, gi_package=None, gi_version=None):\n    try:\n        if gi is not None:\n            gi.require_version(gi_package, gi_version)\n        return importlib.import_module(module)\n    except (ImportError, ValueError):\n        import sys\n        sys.exit('%s: missing required system package %s' % (NAME, os_package))\n\n\nbattery_icons_style = 'regular'\n\n\ndef _parse_arguments():\n    import argparse\n    arg_parser = argparse.ArgumentParser(\n        prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'\n    )\n    arg_parser.add_argument(\n        '-d',\n        '--debug',\n        action='count',\n        default=0,\n        help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'\n    )\n    arg_parser.add_argument(\n        '-D',\n        '--hidraw',\n        action='store',\n        dest='hidraw_path',\n        metavar='PATH',\n        help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'\n    )\n    arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')\n    arg_parser.add_argument(\n        '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'\n    )\n    arg_parser.add_argument(\n        '-b',\n        '--battery-icons',\n        choices=('regular', 'symbolic', 'solaar'),\n        help='prefer regular battery / symbolic battery / solaar icons'\n    )\n    arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')\n    arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)\n    arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')\n    arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')\n\n    args = arg_parser.parse_args()\n\n    if args.help_actions:\n        _cli.print_help()\n        return\n\n    if args.window is None:\n        args.window = 'show'  # default behaviour is to show main window\n\n    global battery_icons_style\n    battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'\n    global tray_icon_size\n    tray_icon_size = args.tray_icon_size\n\n    import logging\n    if args.debug > 0:\n        log_level = logging.ERROR - 10 * args.debug\n        log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n        logging.basicConfig(level=max(log_level, logging.DEBUG), format=log_format, datefmt='%H:%M:%S')\n    else:\n        logging.root.addHandler(logging.NullHandler())\n        logging.root.setLevel(logging.ERROR)\n\n    if not args.action:\n        if logging.root.isEnabledFor(logging.INFO):\n            logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)\n\n    return args\n\n\n# On first SIGINT, dump threads to stderr; on second, exit\ndef _handlesigint(signal, stack):\n    import signal\n    import sys\n    import faulthandler\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n\n    if _log.isEnabledFor(_INFO):\n        faulthandler.dump_traceback()\n\n    sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))\n\n\ndef main():\n    _require('pyudev', 'python3-pyudev')\n\n    # handle ^C in console\n    import signal\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGINT, _handlesigint)\n\n    args = _parse_arguments()\n    if not args:\n        return\n    if args.action:\n        # if any argument, run comandline and exit\n        return _cli.run(args.action, args.hidraw_path)\n\n    gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')\n    _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')\n\n    udev_file = '42-logitech-unify-permissions.rules'\n    if _log.isEnabledFor(_WARNING) \\\n       and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):\n        _log.warning('Solaar udev file not found in expected location')\n        _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')\n    try:\n        import solaar.ui as ui\n        import solaar.listener as listener\n        listener.setup_scanner(ui.status_changed, ui.error_dialog)\n\n        import solaar.upower as _upower\n        if args.restart_on_wake_up:\n            _upower.watch(listener.start_all, listener.stop_all)\n        else:\n            _upower.watch(lambda: listener.ping_all(True))\n\n        # main UI event loop\n        ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')\n    except Exception:\n        import sys\n        from traceback import format_exc\n        sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/solaar/gtk.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n# -*- python-mode -*-\n# -*- coding: UTF-8 -*-\n\n## Copyright (C) 2012-2013  Daniel Pavel\n##\n## This program is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License along\n## with this program; if not, write to the Free Software Foundation, Inc.,\n## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport importlib\nimport logging\nimport os.path\nimport tempfile\n\nfrom logging import INFO as _INFO\nfrom logging import WARNING as _WARNING\n\nimport solaar.cli as _cli\nimport solaar.i18n as _i18n\n\nfrom solaar import NAME, __version__\n\n_log = logging.getLogger(__name__)\n\n#\n#\n#\n\n\ndef _require(module, os_package, gi=None, gi_package=None, gi_version=None):\n    try:\n        if gi is not None:\n            gi.require_version(gi_package, gi_version)\n        return importlib.import_module(module)\n    except (ImportError, ValueError):\n        import sys\n        sys.exit('%s: missing required system package %s' % (NAME, os_package))\n\n\nbattery_icons_style = 'regular'\ntemp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)\n\n\ndef _parse_arguments():\n    import argparse\n    arg_parser = argparse.ArgumentParser(\n        prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'\n    )\n    arg_parser.add_argument(\n        '-d',\n        '--debug',\n        action='count',\n        default=0,\n        help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'\n    )\n    arg_parser.add_argument(\n        '-D',\n        '--hidraw',\n        action='store',\n        dest='hidraw_path',\n        metavar='PATH',\n        help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'\n    )\n    arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')\n    arg_parser.add_argument(\n        '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'\n    )\n    arg_parser.add_argument(\n        '-b',\n        '--battery-icons',\n        choices=('regular', 'symbolic', 'solaar'),\n        help='prefer regular battery / symbolic battery / solaar icons'\n    )\n    arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')\n    arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)\n    arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')\n    arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')\n\n    args = arg_parser.parse_args()\n\n    if args.help_actions:\n        _cli.print_help()\n        return\n\n    if args.window is None:\n        args.window = 'show'  # default behaviour is to show main window\n\n    global battery_icons_style\n    battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'\n    global tray_icon_size\n    tray_icon_size = args.tray_icon_size\n\n    log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n    log_level = logging.ERROR - 10 * args.debug\n    logging.getLogger('').setLevel(min(log_level, logging.WARNING))\n    file_handler = logging.StreamHandler(temp)\n    file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))\n    file_handler.setFormatter(logging.Formatter(log_format))\n    logging.getLogger('').addHandler(file_handler)\n    if args.debug > 0:\n        stream_handler = logging.StreamHandler()\n        stream_handler.setFormatter(logging.Formatter(log_format))\n        stream_handler.setLevel(log_level)\n        logging.getLogger('').addHandler(stream_handler)\n\n    if not args.action:\n        if _log.isEnabledFor(logging.INFO):\n            logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)\n\n    return args\n\n\n# On first SIGINT, dump threads to stderr; on second, exit\ndef _handlesigint(signal, stack):\n    import signal\n    import sys\n    import faulthandler\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n\n    if _log.isEnabledFor(_INFO):\n        faulthandler.dump_traceback()\n\n    sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))\n\n\ndef main():\n    _require('pyudev', 'python3-pyudev')\n\n    # handle ^C in console\n    import signal\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGINT, _handlesigint)\n\n    args = _parse_arguments()\n    if not args:\n        return\n    if args.action:\n        # if any argument, run comandline and exit\n        return _cli.run(args.action, args.hidraw_path)\n\n    gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')\n    _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')\n\n    udev_file = '42-logitech-unify-permissions.rules'\n    if _log.isEnabledFor(_WARNING) \\\n       and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):\n        _log.warning('Solaar udev file not found in expected location')\n        _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')\n    try:\n        import solaar.ui as ui\n        import solaar.listener as listener\n        listener.setup_scanner(ui.status_changed, ui.error_dialog)\n\n        import solaar.upower as _upower\n        if args.restart_on_wake_up:\n            _upower.watch(listener.start_all, listener.stop_all)\n        else:\n            _upower.watch(lambda: listener.ping_all(True))\n\n        # main UI event loop\n        ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')\n    except Exception:\n        import sys\n        from traceback import format_exc\n        sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))\n\n    temp.close()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/solaar/gtk.py"}]}