#!/usr/bin/env python import os import sys import requests class uploader(): log_path = '/var/log/ansible/hosts' url = '' host = '127.0.0.1' def __init__(self, url='http://10.0.2.100/', host='127.0.0.1'): self.url = url self.host = host def upload_file(self, file_name, content, override=False): values = {'path': file_name, 'content': content} if override: values['clear'] = '1' result = requests.post(self.url, data=values) return result def upload_result(self): has_failure = False for filename in os.listdir(self.log_path): filepath = os.path.join(self.log_path, filename) to_path = 'ansible/%s' % filename if os.path.exists(filepath) and os.path.isfile(filepath): content = "" with open(filepath, 'r') as fd: content = ','.join(fd.readlines()) r = self.upload_file(to_path, '[%s]' % content, True) print 'Content uploaded to %s' % to_path, r if filename.endswith('FAILED'): has_failure = True if not has_failure: to_path = 'ansible/%s_FAILED' % self.host r = self.upload_file(to_path, '[]', True) print 'Content uploaded to %s' % to_path, r def readFileFrom(self, f, lastPosition, limit=20000): """ Returns the last lines of file `f`, from position lastPosition. and the last position limit = max number of characters to read """ BUFSIZ = 1024 f.seek(0, 2) btes = f.tell() block = -1 data = "" length = btes truncated = False # True if a part of log data has been truncated #if (lastPosition <= 0 and length > limit) or (length - lastPosition > limit): # lastPosition = length - limit # truncated = True if lastPosition > btes: lastPosition = 0 size = btes - lastPosition while btes > lastPosition: if abs(block * BUFSIZ) <= size: # Seek back one whole BUFSIZ f.seek(block * BUFSIZ, 2) data = f.read(BUFSIZ) + data else: margin = abs(block * BUFSIZ) - size if length < BUFSIZ: f.seek(0, 0) else: seek = block * BUFSIZ + margin f.seek(seek, 2) data = f.read(BUFSIZ - margin) + data btes -= BUFSIZ block -= 1 f.close() return { 'data': data, 'position': length, 'truncated': truncated } if __name__ == "__main__": ansible_log = "/var/log/vm-bootstrap.log" url = "http://10.0.2.100/" if len(sys.argv) < 3: print "Use: %s upload_url file_to_upload" % sys.argv[0] print "Default: %s %s %s" % (sys.argv[0], url, ansible_log) if len(sys.argv) >= 2: url = sys.argv[1] if len(sys.argv) >= 3: ansible_log = sys.argv[2] uploader = uploader(url=url) state_file = "/opt/.ansible_log.state" log_destination = "ansible/vm-bootstrap.log" current_state = 0 if os.path.exists(state_file): with open(state_file, 'r') as f: current_state = int(f.read()) if os.path.exists(ansible_log): f = open(ansible_log, 'r') content = uploader.readFileFrom(f, current_state) f.close() if content['data']: r = uploader.upload_file(log_destination, content['data']) print 'Content uploaded to %s' % log_destination, r with open(state_file, 'w') as f: f.write(str(content['position'])) else: print 'No Ansible log file found in %s.' % ansible_log # Post Ansible execution result uploader.upload_result()