1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 from __future__ import print_function
34
35 import os
36 import re
37 import socket
38 import sys
39
40 from datetime import datetime
41 from dateutil.tz import tzlocal
42
43 from argparse import ArgumentParser
44
45 import rosgraph
46 import rospy
47
48 from .logger_level_service_caller import LoggerLevelServiceCaller
49 from .logger_level_service_caller import ROSConsoleException
50
51 from rosgraph_msgs.msg import Log
52
53 NAME = 'rosconsole'
54
55
56 -def error(status, msg):
57 print("%s: error: %s" % (NAME, msg), file=sys.stderr)
58 sys.exit(status)
59
62 from optparse import OptionParser
63
64 usage = "usage: %prog list <node>"
65 parser = OptionParser(usage=usage, prog=NAME)
66
67 return parser
68
71 args = argv[2:]
72 parser = _get_cmd_list_optparse()
73 (options, args) = parser.parse_args(args)
74
75 if not args:
76 parser.error("you must specify a node to list loggers")
77 elif len(args) > 1:
78 parser.error("you may only specify one node to list")
79
80 logger_level = LoggerLevelServiceCaller()
81
82 loggers = logger_level.get_loggers(args[0])
83
84 output = '\n'.join(loggers)
85 print(output)
86
89 from optparse import OptionParser
90
91 usage = "usage: %prog set <node> <logger> <level>"
92 levels = ', '.join(LoggerLevelServiceCaller().get_levels())
93 usage += "\n\n <level> must be one of [" + levels + "]"
94 parser = OptionParser(usage=usage, prog=NAME)
95
96 return parser
97
100 args = argv[2:]
101 parser = _get_cmd_set_optparse()
102 (options, args) = parser.parse_args(args)
103
104 if len(args) < 3:
105 parser.error("you must specify a node, a logger and a level")
106
107 logger_level = LoggerLevelServiceCaller()
108 logger_level.get_loggers(args[0])
109
110 if args[1] not in logger_level._current_levels:
111 error(2, "node " + args[0] + " does not contain logger " + args[1])
112
113 level = args[2].lower()
114 if level not in logger_level.get_levels():
115 parser.error("invalid level")
116
117 logger_level.send_logger_change_message(args[0], args[1], args[2])
118
121 from optparse import OptionParser
122
123 usage = "usage: %prog get <node> <logger>"
124 parser = OptionParser(usage=usage, prog=NAME)
125
126 return parser
127
130 args = argv[2:]
131 parser = _get_cmd_get_optparse()
132 (options, args) = parser.parse_args(args)
133
134 if len(args) < 2:
135 parser.error("you must specify a node and a logger")
136
137 logger_level = LoggerLevelServiceCaller()
138 logger_level.get_loggers(args[0])
139
140 if args[1] not in logger_level._current_levels:
141 error(2, "node " + args[0] + " does not contain logger " + args[1])
142
143 print(logger_level._current_levels[args[1]])
144
147
148
149 LEVEL_COLOR = {
150 'DEBUG': 92,
151 'INFO' : 97,
152 'WARN' : 93,
153 'ERROR': 91,
154 'FATAL': 95,
155 }
156
157 LEVEL_MAX_LENGTH = max([len(level) for level in LEVEL_COLOR.keys()])
158
160 self._filter = re.compile(options.filter)
161 self._level = getattr(Log, options.level.upper())
162 self._nocolor = options.nocolor
163 self._verbose = options.verbose
164
165 self._level_string_map = {getattr(Log, level): self._stringify(level) for level in self.LEVEL_COLOR.keys()}
166
167 callback = self._once_callback if options.once else self._callback
168 rospy.Subscriber(options.topic, Log, callback)
169
175
176 @staticmethod
180
182 print('[ {} ] [\033[1m{}\033[21m]: {}'.format(
183 self._level_string_map[msg.level], msg.name, msg.msg))
184
185 if self._verbose:
186 stamp_sec = msg.header.stamp.to_sec()
187 stamp_tz = datetime.fromtimestamp(stamp_sec, tzlocal())
188
189 print(' [{} ({:.6f})] [{}]: {}:{}'.format(
190 stamp_tz, stamp_sec, msg.function, msg.file, msg.line))
191
193 if self._filter.search(msg.name) and msg.level >= self._level:
194 self._print(msg)
195
199
202 parser = ArgumentParser(prog=prog, description='Print logger messages')
203
204 parser.add_argument('filter', metavar='FILTER', type=str, nargs='?', default='.*',
205 help='regular expression to filter the logger name (default: %(default)s)')
206
207 parser.add_argument('-l', '--level', action='store', metavar='LEVEL',
208 type=str, default='warn', dest='level',
209 choices=[level.lower() for level in RosConsoleEcho.get_levels()],
210 help='minimum logger level to print (default: %(default)s)')
211
212 parser.add_argument('-1', '--once', action='store_true', dest='once',
213 help='prints one logger message and exits')
214
215 parser.add_argument('--topic', action='store', metavar='TOPIC',
216 type=str, default='/rosout', dest='topic',
217 help='topic to read the logger messages from (default: %(default)s)')
218
219 parser.add_argument('--nocolor', action='store_true', help='output without color')
220
221 parser.add_argument('-v', '--verbose', action='store_true', help='print full logger details')
222
223 return parser
224
227 parser = _get_cmd_echo_argparse(' '.join([os.path.basename(argv[0]), argv[1]]))
228 args = parser.parse_args(argv[2:])
229
230 rospy.init_node('rosconsole', anonymous=True)
231
232 rosconsole = RosConsoleEcho(args)
233
234 rospy.spin()
235
238 print("""rosconsole is a command-line tool for configuring the logger level of ROS nodes.
239
240 Commands:
241 \trosconsole get\tdisplay level for a logger
242 \trosconsole list\tlist loggers for a node
243 \trosconsole set\tset level for a logger
244 \trosconsole echo\tprint logger messages
245
246 Type rosconsole <command> -h for more detailed usage, e.g. 'rosconsole list -h'
247 """)
248 sys.exit(getattr(os, 'EX_USAGE', 1))
249
250
251 -def main(argv=None):
252 if argv is None:
253 argv = sys.argv
254
255
256
257 rospy.init_node('rosconsole', anonymous=True)
258 argv = rospy.myargv(argv)
259
260
261 if len(argv) == 1:
262 _fullusage()
263
264 try:
265 command = argv[1]
266 if command == 'get':
267 _rosconsole_cmd_get(argv)
268 elif command == 'list':
269 _rosconsole_cmd_list(argv)
270 elif command == 'set':
271 _rosconsole_cmd_set(argv)
272 elif command == 'echo':
273 _rosconsole_cmd_echo(argv)
274 else:
275 _fullusage()
276 except socket.error as e:
277 error(1,
278 "Network communication failed; most likely failed to communicate with master: %s" % e)
279 except rosgraph.MasterException as e:
280
281 error(1, str(e))
282 except ROSConsoleException as e:
283 error(1, str(e))
284 except KeyboardInterrupt:
285 pass
286