mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 23:45:44 +07:00
[IMP] runbot: add log metadata
This commit is contained in:
parent
1ed9278d6e
commit
d1cd7f3684
@ -409,27 +409,26 @@ class BuildError(models.Model):
|
|||||||
build_error_contents = self.env['runbot.build.error.content']
|
build_error_contents = self.env['runbot.build.error.content']
|
||||||
# add build ids to already detected errors
|
# 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_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
|
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
|
# create an error for the remaining entries
|
||||||
for fingerprint, logs in hash_dict.items():
|
for fingerprint, logs in hash_dict.items():
|
||||||
if fingerprint in existing_fingerprints:
|
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
|
continue
|
||||||
new_build_error_content = self.env['runbot.build.error.content'].create({
|
new_build_error_content = self.env['runbot.build.error.content'].create({
|
||||||
'content': logs[0].message,
|
'content': logs[0].message,
|
||||||
'module_name': logs[0].name.removeprefix('odoo.').removeprefix('addons.'),
|
'module_name': logs[0].name.removeprefix('odoo.').removeprefix('addons.'),
|
||||||
'file_path': logs[0].path,
|
'file_path': logs[0].path,
|
||||||
'function': logs[0].func,
|
'function': logs[0].func,
|
||||||
|
'metadata': logs[0].metadata,
|
||||||
})
|
})
|
||||||
build_error_contents |= new_build_error_content
|
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:
|
for build_error_content in build_error_contents:
|
||||||
logs = hash_dict[build_error_content.fingerprint]
|
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")
|
error_display_id = fields.Integer(compute='_compute_error_display_id', string="Error id")
|
||||||
content = fields.Text('Error message', required=True)
|
content = fields.Text('Error message', required=True)
|
||||||
cleaned_content = fields.Text('Cleaned error message')
|
cleaned_content = fields.Text('Cleaned error message')
|
||||||
|
metadata = JsonDictField('Metadata')
|
||||||
summary = fields.Char('Content summary', compute='_compute_summary', store=False)
|
summary = fields.Char('Content summary', compute='_compute_summary', store=False)
|
||||||
module_name = fields.Char('Module name') # name in ir_logging
|
module_name = fields.Char('Module name') # name in ir_logging
|
||||||
file_path = fields.Char('File Path') # path in ir logging
|
file_path = fields.Char('File Path') # path in ir logging
|
||||||
|
@ -94,10 +94,21 @@ class Host(models.Model):
|
|||||||
path character varying NOT NULL,
|
path character varying NOT NULL,
|
||||||
line character varying NOT NULL,
|
line character varying NOT NULL,
|
||||||
type character varying NOT NULL,
|
type character varying NOT NULL,
|
||||||
|
metadata jsonb,
|
||||||
message text NOT NULL);
|
message text NOT NULL);
|
||||||
""")
|
""")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.exception('Failed to create local logs database: %s', 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):
|
def _bootstrap_db_template(self):
|
||||||
""" boostrap template database if needed """
|
""" boostrap template database if needed """
|
||||||
@ -237,7 +248,7 @@ class Host(models.Model):
|
|||||||
query = f"""
|
query = f"""
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM (
|
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
|
FROM ir_logging
|
||||||
)
|
)
|
||||||
AS ir_logs
|
AS ir_logs
|
||||||
|
@ -5,6 +5,7 @@ import logging
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from ..common import pseudo_markdown
|
from ..common import pseudo_markdown
|
||||||
|
from ..fields import JsonDictField
|
||||||
from odoo import models, fields, tools, api
|
from odoo import models, fields, tools, api
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
from odoo.tools import html_escape
|
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})
|
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
|
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)
|
dbname = fields.Char(string='Database Name', index=False)
|
||||||
|
metadata = JsonDictField('Metadata')
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
|
@ -221,6 +221,7 @@
|
|||||||
</group>
|
</group>
|
||||||
<group name="build_error_group" string="Base info" col="2">
|
<group name="build_error_group" string="Base info" col="2">
|
||||||
<field name="content" readonly="1"/>
|
<field name="content" readonly="1"/>
|
||||||
|
<field name="metadata" readonly="1"/>
|
||||||
<field name="module_name" readonly="1"/>
|
<field name="module_name" readonly="1"/>
|
||||||
<field name="function" readonly="1"/>
|
<field name="function" readonly="1"/>
|
||||||
<field name="file_path" readonly="1"/>
|
<field name="file_path" readonly="1"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user