#!/usr/bin/python3 # -*- coding: utf-8 -*- import glob import re import os import sys import subprocess import urllib import json import time import uuid # define regexps regex_process_pid = re.compile(r'/([^/.]+?)\.(\d+?)\.(\d+?)\.core') regex_offset = re.compile(r'#0\s+?([\dxa-f]+?)\s') regex_extension_replacement = re.compile(r'\.zip$') regex_extension_replacement2 = re.compile(r'\.core$') # BEGIN helper functions------------------------------------------------------------------------------------------------ def write_to_log(msg): msg = time.ctime() + ' ' + msg print(msg) def run_shell(cmd): pipe = subprocess.PIPE p = subprocess.Popen(cmd, shell=True, stdin=pipe, stdout=pipe, stderr=pipe, close_fds=True, cwd='/') return p.stdout.read(), p.stderr.read() def run_shell_get_result(cmd): result = subprocess.call(cmd, shell=True) return result def check_size_static(core_file): size_1 = os.path.getsize(core_file) time.sleep(5) size_2 = os.path.getsize(core_file) return size_1 == size_2 # END helper functions-------------------------------------------------------------------------------------------------- # BEGIN prepare date---------------------------------------------------------------------------------------------------- def get_pid_process_ctime(core_file): rez = regex_process_pid.search(core_file) process = rez.groups()[0] ctime = rez.groups()[1] pid = rez.groups()[2] return process, ctime, pid def get_platform_offset(core_file, process): # run gdb for getting offset of core cmd = 'echo -e "bt\nexit" | gdb /opt/1C/v8.3/x86_64/' + process + ' ' + core_file (gdb_result, gdb_error) = run_shell(cmd) if not gdb_result: offset = '000000000000' platform = '8.3.0.0000' write_to_log('cant work with gdb: ' + gdb_error) else: rez = regex_offset.search(gdb_result) if rez is None: offset = '000000000000' else: offset = rez.groups()[0] offset = offset[6:-1] # getting platform version cmd = 'strings /opt/1C/v8.3/x86_64/' + process + """ | grep -oP '[8-9]\.[3-90]\.\d\d?\.\d{2,4}' """ (ver_result, ver_error) = run_shell(cmd) if ver_result: platform = ver_result.strip() else: platform = '8.3.0.0000' return platform, offset def get_creation_date_string(ctime): ctime_sturct = time.localtime(int(ctime)) ctime_string = '_%.4d%.2d%.2d%.2d%.2d%.2d_' % (ctime_sturct[0], ctime_sturct[1], ctime_sturct[2], ctime_sturct[3], ctime_sturct[4], ctime_sturct[5]) creation_date = '%.4d-%.2d-%.2dT%.2d:%.2d:%.2d' % (ctime_sturct[0], ctime_sturct[1], ctime_sturct[2], ctime_sturct[3], ctime_sturct[4], ctime_sturct[5]) return ctime_string, creation_date def get_file_name(process, platform, offset, ctime_string, pid): return process + '_' + platform + '_' + offset + ctime_string + pid + '.core' def get_file_size_hostname(core_file): file_size = os.path.getsize(core_file) hostname = os.uname()[1] return file_size, hostname def make_libs_tar(core_file, process): if os.path.exists(libs_file): os.remove(libs_file) cmd = """echo -e "info shared\nq" | """ cmd += """ gdb /opt/1C/v8.3/x86_64/""" + process + " " + core_file + """ 2>/dev/null | """ cmd += """ grep 0x0000 | grep -v /opt/1C/v8.3 | grep -v ?? | perl -alne 'print $F[-1]' | """ cmd += """ while read file; do tar --dereference --append -f """ + libs_file + """ $file 2> /dev/null ; done""" stdout, stderr = run_shell(cmd) # Если стек не раскрылся, то создадим пустой файл if not os.path.exists(libs_file): cmd = 'touch ' + libs_file run_shell_get_result(cmd) if stderr: write_to_log('cant work with gdb and make libs tar, result: ' + str(stderr)) if os.path.getsize(libs_file) == 0: write_to_log('libs_file size = 0.') def change_extension(core_gz_file): core_gz_file = regex_extension_replacement.sub('.tar.gz', core_gz_file) return regex_extension_replacement2.sub('.tar.gz', core_gz_file) # END prepare date------------------------------------------------------------------------------------------------------ def gz_core_file(core_file, file_name): # Костыль, меняем расшинерие на gz core_gz_file = os.path.basename(file_name) core_gz_file = change_extension(core_gz_file) # Зипуем cmd = 'cd {} && mv {} {} && '.format(cores_dir, core_file, file_name) cmd += 'tar -czf {} {} {} 2>/dev/null && '.format(core_gz_file, file_name, libs_short_file) cmd += 'rm -f {} && rm -f {}'.format(file_name, libs_short_file) rez = run_shell_get_result(cmd) # Если не получилось загзиповать, то выходим из процедуры if rez: write_to_log('cant work with tar') return # BEGIN main program --------------------------------------------------------------------------------------------------- def work_with_dump(core_file): while not check_size_static(core_file): print('{} file size: {}'.format(core_file, os.path.getsize(core_file))) process, ctime, pid = get_pid_process_ctime(core_file) platform, offset = get_platform_offset(core_file, process) ctime_string, creation_date = get_creation_date_string(ctime) make_libs_tar(core_file, process) file_name = get_file_name(process, platform, offset, ctime_string, pid) gz_core_file(core_file, file_name) cores_dir = '/tmp/cores/' # директория в которой должны лежать дампы libs_short_file = 'libs.tar' libs_file = os.path.join(cores_dir, 'libs.tar') if __name__ == "__main__": # finding core files cores_path = cores_dir + '*.core*' for file in glob.glob(cores_path): work_with_dump(file)