[IMP] runbot: add log metadata

This commit is contained in:
Xavier-Do 2025-03-03 10:56:05 +01:00
parent 1ed9278d6e
commit d1cd7f3684
4 changed files with 24 additions and 10 deletions

View File

@ -409,27 +409,26 @@ class BuildError(models.Model):
build_error_contents = self.env['runbot.build.error.content']
# add build ids to already detected errors
existing_errors_contents = self.env['runbot.build.error.content'].search([('fingerprint', 'in', list(hash_dict.keys())), ('error_id.active', '=', True)])
existing_fingerprints = existing_errors_contents.mapped('fingerprint')
existing_fingerprints = {error.fingerprint: error for error in existing_errors_contents}
build_error_contents |= existing_errors_contents
# for build_error_content in existing_errors_contents:
# logs = hash_dict[build_error_content.fingerprint]
# # update filepath if it changed. This is optionnal and mainly there in case we adapt the OdooRunner log
# if logs[0].path != build_error_content.file_path:
# build_error_content.file_path = logs[0].path
# build_error_content.function = logs[0].func
# create an error for the remaining entries
for fingerprint, logs in hash_dict.items():
if fingerprint in existing_fingerprints:
# metadata update, keep this for a while
error = existing_fingerprints[fingerprint]
if not error.metadata and logs[0].metadata:
error.metadata = logs[0].metadata
continue
new_build_error_content = self.env['runbot.build.error.content'].create({
'content': logs[0].message,
'module_name': logs[0].name.removeprefix('odoo.').removeprefix('addons.'),
'file_path': logs[0].path,
'function': logs[0].func,
'metadata': logs[0].metadata,
})
build_error_contents |= new_build_error_content
existing_fingerprints.append(fingerprint)
existing_fingerprints[fingerprint] = new_build_error_content
for build_error_content in build_error_contents:
logs = hash_dict[build_error_content.fingerprint]
@ -474,6 +473,7 @@ class BuildErrorContent(models.Model):
error_display_id = fields.Integer(compute='_compute_error_display_id', string="Error id")
content = fields.Text('Error message', required=True)
cleaned_content = fields.Text('Cleaned error message')
metadata = JsonDictField('Metadata')
summary = fields.Char('Content summary', compute='_compute_summary', store=False)
module_name = fields.Char('Module name') # name in ir_logging
file_path = fields.Char('File Path') # path in ir logging

View File

@ -94,10 +94,21 @@ class Host(models.Model):
path character varying NOT NULL,
line character varying NOT NULL,
type character varying NOT NULL,
metadata jsonb,
message text NOT NULL);
""")
except Exception as e:
_logger.exception('Failed to create local logs database: %s', e)
else:
# TODO cleanup remove in 20.0
with local_pg_cursor(logs_db_name) as local_cr:
local_cr.execute("""SELECT 1
FROM information_schema.columns
WHERE table_name='ir_logging' and column_name='metadata'""")
if not local_cr.fetchone():
_logger.info('Adding metadata column to ir_logging table')
local_cr.execute("""ALTER TABLE ir_logging ADD COLUMN metadata jsonb""")
def _bootstrap_db_template(self):
""" boostrap template database if needed """
@ -237,7 +248,7 @@ class Host(models.Model):
query = f"""
SELECT *
FROM (
SELECT id, create_date, name, level, dbname, func, path, line, type, message, split_part(dbname, '-', 1) as build_id
SELECT id, create_date, name, level, dbname, func, path, line, type, message, split_part(dbname, '-', 1) as build_id, metadata
FROM ir_logging
)
AS ir_logs

View File

@ -5,6 +5,7 @@ import logging
from collections import defaultdict
from ..common import pseudo_markdown
from ..fields import JsonDictField
from odoo import models, fields, tools, api
from odoo.exceptions import UserError
from odoo.tools import html_escape
@ -24,6 +25,7 @@ class IrLogging(models.Model):
type = fields.Selection(selection_add=TYPES, string='Type', required=True, index=True, ondelete={t[0]: 'cascade' for t in TYPES})
error_content_id = fields.Many2one('runbot.build.error.content', compute='_compute_known_error') # remember to never store this field
dbname = fields.Char(string='Database Name', index=False)
metadata = JsonDictField('Metadata')
@api.model_create_multi
def create(self, vals_list):

View File

@ -221,6 +221,7 @@
</group>
<group name="build_error_group" string="Base info" col="2">
<field name="content" readonly="1"/>
<field name="metadata" readonly="1"/>
<field name="module_name" readonly="1"/>
<field name="function" readonly="1"/>
<field name="file_path" readonly="1"/>