def _enumerate_logs(queue, user, users_dir, limit=None): """ Enumerates all of the user's logs and sends the client a "logging_logs" message with the result. If *limit* is given, only return the specified logs. Works just like MySQL: limit="5,10" will retrieve logs 5-10. """ logs_dir = os.path.join(users_dir, "logs") log_files = os.listdir(logs_dir) log_files = [a for a in log_files if a.endswith(".golog")] # Only gologs log_files.sort() # Should put them in order by date log_files.reverse() # Make the newest ones first out_dict = {} for log in log_files: metadata = {} log_path = os.path.join(logs_dir, log) logfile = gzip.open(log_path) metadata = get_or_update_metadata(log_path, user) metadata["size"] = os.stat(log_path).st_size out_dict["log"] = metadata message = {"logging_log": out_dict} queue.put(message) # If we go too quick sometimes the IOLoop will miss a message time.sleep(0.01) queue.put("complete")
def _enumerate_logs(queue, user, users_dir, limit=None): """ Enumerates all of the user's logs and sends the client a "logging_logs" message with the result. If *limit* is given, only return the specified logs. Works just like MySQL: limit="5,10" will retrieve logs 5-10. """ logs_dir = os.path.join(users_dir, "logs") log_files = os.listdir(logs_dir) log_files = [a for a in log_files if a.endswith('.golog')] # Only gologs log_files.sort() # Should put them in order by date log_files.reverse() # Make the newest ones first out_dict = {} for log in log_files: metadata = {} log_path = os.path.join(logs_dir, log) logfile = gzip.open(log_path) metadata = get_or_update_metadata(log_path, user) metadata['size'] = os.stat(log_path).st_size out_dict['log'] = metadata message = {'logging_log': out_dict} queue.put(message) # If we go too quick sometimes the IOLoop will miss a message time.sleep(0.01) queue.put('complete')
def _retrieve_log_flat(queue, settings): """ Writes the given *log_filename* to *queue* in a flat format equivalent to:: ./logviewer.py --flat log_filename *settings* - A dict containing the *log_filename*, *colors*, and *theme* to use when generating the HTML output. """ out_dict = { 'result': "", 'log': "", 'metadata': {}, } # Local variables gateone_dir = settings['gateone_dir'] user = settings['user'] users_dir = settings['users_dir'] container = settings['container'] prefix = settings['prefix'] log_filename = settings['log_filename'] theme = "%s.css" % settings['theme'] colors = "%s.css" % settings['colors'] logs_dir = os.path.join(users_dir, "logs") log_path = os.path.join(logs_dir, log_filename) if os.path.exists(log_path): out_dict['metadata'] = get_or_update_metadata(log_path, user) out_dict['metadata']['filename'] = log_filename out_dict['result'] = "Success" # Use the terminal emulator to create nice HTML-formatted output from terminal import Terminal terminal_emulator = Terminal term = terminal_emulator(rows=100, cols=300) flattened_log = flatten_log(log_path) flattened_log.replace('\n', '\r\n') # Needed to emulate an actual term term.write(flattened_log) scrollback, screen = term.dump_html() # Join them together log_lines = scrollback + screen out_dict['log'] = log_lines else: out_dict['result'] = _("ERROR: Log not found") message = {'logging_log_flat': out_dict} queue.put(message)
def _retrieve_log_flat(queue, settings): """ Writes the given *log_filename* to *queue* in a flat format equivalent to:: ./logviewer.py --flat log_filename *settings* - A dict containing the *log_filename*, *colors*, and *theme* to use when generating the HTML output. """ out_dict = {"result": "", "log": "", "metadata": {}} # Local variables gateone_dir = settings["gateone_dir"] user = settings["user"] users_dir = settings["users_dir"] container = settings["container"] prefix = settings["prefix"] log_filename = settings["log_filename"] theme = "%s.css" % settings["theme"] colors = "%s.css" % settings["colors"] logs_dir = os.path.join(users_dir, "logs") log_path = os.path.join(logs_dir, log_filename) if os.path.exists(log_path): out_dict["metadata"] = get_or_update_metadata(log_path, user) out_dict["metadata"]["filename"] = log_filename out_dict["result"] = "Success" # Use the terminal emulator to create nice HTML-formatted output from terminal import Terminal terminal_emulator = Terminal term = terminal_emulator(rows=100, cols=300) flattened_log = flatten_log(log_path) flattened_log.replace("\n", "\r\n") # Needed to emulate an actual term term.write(flattened_log) scrollback, screen = term.dump_html() # Join them together log_lines = scrollback + screen out_dict["log"] = log_lines else: out_dict["result"] = "ERROR: Log not found" message = {"logging_log_flat": out_dict} queue.put(message)
def _save_log_playback(queue, settings): """ Writes a JSON-encoded message to the client containing the log in a self-contained HTML format similar to:: ./logviewer.py log_filename The difference between this function and :py:meth:`_retrieve_log_playback` is that this one instructs the client to save the file to disk instead of opening it in a new window. *settings* - A dict containing the *log_filename*, *colors*, and *theme* to use when generating the HTML output. *settings['log_filename']* - The name of the log to display. *settings['colors']* - The CSS color scheme to use when generating output. *settings['theme']* - The CSS theme to use when generating output. The output will look like this:: { 'result': "Success", 'data': <HTML rendered output>, 'mimetype': 'text/html' 'filename': <filename of the log recording> } It is expected that the client will create a new window with the result of this method. """ # print("Running retrieve_log_playback(%s)" % settings); out_dict = {"result": "Success", "mimetype": "text/html", "data": ""} # Will be replace with the rendered template # Local variables gateone_dir = settings["gateone_dir"] user = settings["user"] users_dir = settings["users_dir"] container = settings["container"] prefix = settings["prefix"] url_prefix = settings["url_prefix"] log_filename = settings["log_filename"] short_logname = log_filename.split(".golog")[0] out_dict["filename"] = "%s.html" % short_logname theme = "%s.css" % settings["theme"] colors = "%s.css" % settings["colors"] # Important paths # NOTE: Using os.path.join() in case Gate One can actually run on Windows # some day. logs_dir = os.path.join(users_dir, "logs") log_path = os.path.join(logs_dir, log_filename) templates_path = os.path.join(gateone_dir, "templates") colors_path = os.path.join(templates_path, "term_colors") themes_path = os.path.join(templates_path, "themes") plugins_path = os.path.join(gateone_dir, "plugins") logging_plugin_path = os.path.join(plugins_path, "logging") template_path = os.path.join(logging_plugin_path, "templates") # recording format: # {"screen": [log lines], "time":"2011-12-20T18:00:01.033Z"} # Actual method logic if os.path.exists(log_path): # Next we render the theme and color templates so we can pass them to # our final template out_dict["metadata"] = get_or_update_metadata(log_path, user) try: rows = out_dict["metadata"]["rows"] cols = out_dict["metadata"]["cols"] except KeyError: # Log was created before rows/cols metadata was included via termio.py # Use some large values to ensure nothing wraps and hope for the best: rows = 40 cols = 500 with open(os.path.join(colors_path, colors)) as f: colors_file = f.read() colors_template = tornado.template.Template(colors_file) rendered_colors = colors_template.generate(container=container, prefix=prefix, url_prefix=url_prefix) with open(os.path.join(themes_path, theme)) as f: theme_file = f.read() theme_template = tornado.template.Template(theme_file) # Setup our 256-color support CSS: colors_256 = "" for i in xrange(256): fg = "#%s span.fx%s {color: #%s;}" % (container, i, COLORS_256[i]) bg = "#%s span.bx%s {background-color: #%s;} " % (container, i, COLORS_256[i]) colors_256 += "%s %s" % (fg, bg) colors_256 += "\n" rendered_theme = theme_template.generate( container=container, prefix=prefix, colors_256=colors_256, url_prefix=url_prefix ) # NOTE: 'colors' are customizable but colors_256 is universal. That's # why they're separate. # Lastly we render the actual HTML template file # NOTE: Using Loader() directly here because I was getting strange EOF # errors trying to do it the other way :) loader = tornado.template.Loader(template_path) playback_template = loader.load("playback_log.html") recording = retrieve_log_frames(log_path, rows, cols) preview = "false" playback_html = playback_template.generate( prefix=prefix, container=container, theme=rendered_theme, colors=rendered_colors, preview=preview, recording=json_encode(recording), url_prefix=url_prefix, ) out_dict["data"] = playback_html else: out_dict["result"] = "ERROR: Log not found" message = {"save_file": out_dict} queue.put(message)
def _retrieve_log_playback(queue, settings): """ Writes a JSON-encoded message to the client containing the log in a self-contained HTML format similar to:: ./logviewer.py log_filename *settings* - A dict containing the *log_filename*, *colors*, and *theme* to use when generating the HTML output. *settings['log_filename']* - The name of the log to display. *settings['colors']* - The CSS color scheme to use when generating output. *settings['theme']* - The CSS theme to use when generating output. *settings['where']* - Whether or not the result should go into a new window or an iframe. The output will look like this:: { 'result': "Success", 'log': <HTML rendered output>, 'metadata': {<metadata of the log>} } It is expected that the client will create a new window with the result of this method. """ #print("Running retrieve_log_playback(%s)" % settings); if 'where' not in settings: # Avoids a KeyError if it is missing settings['where'] = None out_dict = { 'result': "", 'html': "", # Will be replace with the rendered template 'metadata': {}, 'where': settings['where'] # Just gets passed as-is back to the client } # Local variables gateone_dir = settings['gateone_dir'] user = settings['user'] users_dir = settings['users_dir'] container = settings['container'] prefix = settings['prefix'] url_prefix = settings['url_prefix'] log_filename = settings['log_filename'] theme = "%s.css" % settings['theme'] colors = "%s.css" % settings['colors'] # Important paths # NOTE: Using os.path.join() in case Gate One can actually run on Windows # some day. logs_dir = os.path.join(users_dir, "logs") log_path = os.path.join(logs_dir, log_filename) templates_path = os.path.join(gateone_dir, 'templates') colors_path = os.path.join(templates_path, 'term_colors') themes_path = os.path.join(templates_path, 'themes') plugins_path = os.path.join(gateone_dir, 'plugins') logging_plugin_path = os.path.join(plugins_path, 'logging') template_path = os.path.join(logging_plugin_path, 'templates') # recording format: # {"screen": [log lines], "time":"2011-12-20T18:00:01.033Z"} # Actual method logic if os.path.exists(log_path): # First we setup the basics out_dict['metadata'] = get_or_update_metadata(log_path, user) out_dict['metadata']['filename'] = log_filename try: rows = out_dict['metadata']['rows'] cols = out_dict['metadata']['cols'] except KeyError: # Log was created before rows/cols metadata was included via termio.py # Use some large values to ensure nothing wraps and hope for the best: rows = 40 cols = 500 out_dict['result'] = "Success" # TODO: Add more error checking # Next we render the theme and color templates so we can pass them to # our final template with open(os.path.join(colors_path, colors)) as f: colors_file = f.read() colors_template = tornado.template.Template(colors_file) rendered_colors = colors_template.generate( container=container, prefix=prefix, url_prefix=url_prefix ) with open(os.path.join(themes_path, theme)) as f: theme_file = f.read() theme_template = tornado.template.Template(theme_file) # Setup our 256-color support CSS: colors_256 = "" from gateone import COLORS_256 for i in xrange(256): fg = "#%s span.fx%s {color: #%s;}" % ( container, i, COLORS_256[i]) bg = "#%s span.bx%s {background-color: #%s;} " % ( container, i, COLORS_256[i]) fg_rev = "#%s span.reverse.fx%s {background-color: #%s; color: inherit;}" % ( container, i, COLORS_256[i]) bg_rev = "#%s span.reverse.bx%s {color: #%s; background-color: inherit;} " % ( container, i, COLORS_256[i]) colors_256 += "%s %s %s %s" % (fg, bg, fg_rev, bg_rev) colors_256 += "\n" rendered_theme = theme_template.generate( container=container, prefix=prefix, colors_256=colors_256, url_prefix=url_prefix ) # NOTE: 'colors' are customizable but colors_256 is universal. That's # why they're separate. # Lastly we render the actual HTML template file # NOTE: Using Loader() directly here because I was getting strange EOF # errors trying to do it the other way :) loader = tornado.template.Loader(template_path) playback_template = loader.load('playback_log.html') preview = 'false' if settings['where']: preview = 'true' recording = retrieve_log_frames(log_path, rows, cols, limit=50) else: recording = retrieve_log_frames(log_path, rows, cols) playback_html = playback_template.generate( prefix=prefix, container=container, theme=rendered_theme, colors=rendered_colors, preview=preview, recording=json_encode(recording), url_prefix=url_prefix ) out_dict['html'] = playback_html else: out_dict['result'] = _("ERROR: Log not found") message = {'logging_log_playback': out_dict} queue.put(message)
def _save_log_playback(queue, settings): """ Writes a JSON-encoded message to the client containing the log in a self-contained HTML format similar to:: ./logviewer.py log_filename The difference between this function and :py:meth:`_retrieve_log_playback` is that this one instructs the client to save the file to disk instead of opening it in a new window. *settings* - A dict containing the *log_filename*, *colors*, and *theme* to use when generating the HTML output. *settings['log_filename']* - The name of the log to display. *settings['colors']* - The CSS color scheme to use when generating output. *settings['theme']* - The CSS theme to use when generating output. The output will look like this:: { 'result': "Success", 'data': <HTML rendered output>, 'mimetype': 'text/html' 'filename': <filename of the log recording> } It is expected that the client will create a new window with the result of this method. """ #print("Running retrieve_log_playback(%s)" % settings); out_dict = { 'result': "Success", 'mimetype': 'text/html', 'data': "", # Will be replace with the rendered template } # Local variables gateone_dir = settings['gateone_dir'] user = settings['user'] users_dir = settings['users_dir'] container = settings['container'] prefix = settings['prefix'] url_prefix = settings['url_prefix'] log_filename = settings['log_filename'] short_logname = log_filename.split('.golog')[0] out_dict['filename'] = "%s.html" % short_logname theme = "%s.css" % settings['theme'] colors = "%s.css" % settings['colors'] # Important paths # NOTE: Using os.path.join() in case Gate One can actually run on Windows # some day. logs_dir = os.path.join(users_dir, "logs") log_path = os.path.join(logs_dir, log_filename) templates_path = os.path.join(gateone_dir, 'templates') colors_path = os.path.join(templates_path, 'term_colors') themes_path = os.path.join(templates_path, 'themes') plugins_path = os.path.join(gateone_dir, 'plugins') logging_plugin_path = os.path.join(plugins_path, 'logging') template_path = os.path.join(logging_plugin_path, 'templates') # recording format: # {"screen": [log lines], "time":"2011-12-20T18:00:01.033Z"} # Actual method logic if os.path.exists(log_path): # Next we render the theme and color templates so we can pass them to # our final template out_dict['metadata'] = get_or_update_metadata(log_path, user) try: rows = out_dict['metadata']['rows'] cols = out_dict['metadata']['cols'] except KeyError: # Log was created before rows/cols metadata was included via termio.py # Use some large values to ensure nothing wraps and hope for the best: rows = 40 cols = 500 with open(os.path.join(colors_path, colors)) as f: colors_file = f.read() colors_template = tornado.template.Template(colors_file) rendered_colors = colors_template.generate(container=container, prefix=prefix, url_prefix=url_prefix) with open(os.path.join(themes_path, theme)) as f: theme_file = f.read() theme_template = tornado.template.Template(theme_file) # Setup our 256-color support CSS: colors_256 = "" from gateone import COLORS_256 for i in xrange(256): fg = "#%s span.fx%s {color: #%s;}" % (container, i, COLORS_256[i]) bg = "#%s span.bx%s {background-color: #%s;} " % (container, i, COLORS_256[i]) colors_256 += "%s %s" % (fg, bg) colors_256 += "\n" rendered_theme = theme_template.generate(container=container, prefix=prefix, colors_256=colors_256, url_prefix=url_prefix) # NOTE: 'colors' are customizable but colors_256 is universal. That's # why they're separate. # Lastly we render the actual HTML template file # NOTE: Using Loader() directly here because I was getting strange EOF # errors trying to do it the other way :) loader = tornado.template.Loader(template_path) playback_template = loader.load('playback_log.html') recording = retrieve_log_frames(log_path, rows, cols) preview = 'false' playback_html = playback_template.generate( prefix=prefix, container=container, theme=rendered_theme, colors=rendered_colors, preview=preview, recording=json_encode(recording), url_prefix=url_prefix) out_dict['data'] = playback_html else: out_dict['result'] = _("ERROR: Log not found") message = {'save_file': out_dict} queue.put(message)