def store_cloudwatch_logs(log_group_name, log_stream_name, log_output, start_time=None): if not aws_stack.is_service_enabled("logs"): return start_time = start_time or int(time.time() * 1000) logs_client = aws_stack.connect_to_service("logs") log_output = to_str(log_output) # make sure that the log group exists log_groups = logs_client.describe_log_groups()["logGroups"] log_groups = [lg["logGroupName"] for lg in log_groups] if log_group_name not in log_groups: try: logs_client.create_log_group(logGroupName=log_group_name) except Exception as e: if "ResourceAlreadyExistsException" in str(e): # this can happen in certain cases, possibly due to a race condition pass else: raise e # create a new log stream for this lambda invocation logs_client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name) # store new log events under the log stream finish_time = int(time.time() * 1000) # fix for log lines that were merged into a singe line, e.g., "log line 1 ... \x1b[32mEND RequestId ..." log_output = log_output.replace("\\x1b", "\n\\x1b") log_output = log_output.replace("\x1b", "\n\x1b") log_lines = log_output.split("\n") time_diff_per_line = float(finish_time - start_time) / float( len(log_lines)) log_events = [] for i, line in enumerate(log_lines): if not line: continue # simple heuristic: assume log lines were emitted in regular intervals log_time = start_time + float(i) * time_diff_per_line event = {"timestamp": int(log_time), "message": line} log_events.append(event) if not log_events: return logs_client.put_log_events(logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=log_events)
def store_cloudwatch_logs(log_group_name, log_stream_name, log_output, start_time=None): if not aws_stack.is_service_enabled('logs'): return start_time = start_time or int(time.time() * 1000) logs_client = aws_stack.connect_to_service('logs') log_output = to_str(log_output) # make sure that the log group exists log_groups = logs_client.describe_log_groups()['logGroups'] log_groups = [lg['logGroupName'] for lg in log_groups] if log_group_name not in log_groups: try: logs_client.create_log_group(logGroupName=log_group_name) except Exception as e: if 'ResourceAlreadyExistsException' in str(e): # this can happen in certain cases, possibly due to a race condition pass else: raise e # create a new log stream for this lambda invocation logs_client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name) # store new log events under the log stream finish_time = int(time.time() * 1000) log_lines = log_output.split('\n') time_diff_per_line = float(finish_time - start_time) / float( len(log_lines)) log_events = [] for i, line in enumerate(log_lines): if not line: continue # simple heuristic: assume log lines were emitted in regular intervals log_time = start_time + float(i) * time_diff_per_line event = {'timestamp': int(log_time), 'message': line} log_events.append(event) if not log_events: return logs_client.put_log_events(logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=log_events)
def _store_logs(self, func_details, log_output, invocation_time): if not aws_stack.is_service_enabled('logs'): return logs_client = aws_stack.connect_to_service('logs') log_group_name = '/aws/lambda/%s' % func_details.name() time_str = time.strftime('%Y/%m/%d', time.gmtime(invocation_time)) log_stream_name = '%s/[$LATEST]%s' % (time_str, short_uid()) # make sure that the log group exists log_groups = logs_client.describe_log_groups()['logGroups'] log_groups = [lg['logGroupName'] for lg in log_groups] if log_group_name not in log_groups: logs_client.create_log_group(logGroupName=log_group_name) # create a new log stream for this lambda invocation logs_client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name) # store new log events under the log stream invocation_time = invocation_time finish_time = int(time.time() * 1000) log_lines = log_output.split('\n') time_diff_per_line = float(finish_time - invocation_time) / float( len(log_lines)) log_events = [] for i, line in enumerate(log_lines): if not line: continue # simple heuristic: assume log lines were emitted in regular intervals log_time = invocation_time + float(i) * time_diff_per_line event = {'timestamp': int(log_time), 'message': line} log_events.append(event) if not log_events: return logs_client.put_log_events(logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=log_events)