mirror of
https://github.com/odoo/runbot.git
synced 2025-03-16 16:05:42 +07:00
[IMP] runbot: add an error log model based on a SQL view
With this commit, a new model is introduced to facilitate the tracking of the build errors. Its based on an SQL view (Thanks @Xavier-Do), that way, there is no new table in DB and this view is also useful from the PSQL CLI. In the UI, the search for errors easier than manipulate the ir_logging view because the builds informations can be used in search and filters.
This commit is contained in:
parent
7382aa6b79
commit
c49e422a25
@ -18,6 +18,7 @@
|
||||
'views/build_views.xml',
|
||||
'views/host_views.xml',
|
||||
'views/build_error_views.xml',
|
||||
'views/error_log_views.xml',
|
||||
'views/config_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'templates/frontend.xml',
|
||||
|
@ -33,6 +33,7 @@ def make_selection(array):
|
||||
class runbot_build(models.Model):
|
||||
_name = "runbot.build"
|
||||
_order = 'id desc'
|
||||
_rec_name = 'id'
|
||||
|
||||
branch_id = fields.Many2one('runbot.branch', 'Branch', required=True, ondelete='cascade', index=True)
|
||||
repo_id = fields.Many2one(related='branch_id.repo_id', readonly=True, store=True)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo import models, fields, api, tools
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@ -47,3 +47,100 @@ CREATE TRIGGER runbot_new_logging BEFORE INSERT ON ir_logging
|
||||
FOR EACH ROW EXECUTE PROCEDURE runbot_set_logging_build();
|
||||
|
||||
""")
|
||||
|
||||
|
||||
class RunbotErrorLog(models.Model):
|
||||
_name = "runbot.error.log"
|
||||
_auto = False
|
||||
_order = 'id desc'
|
||||
|
||||
id = fields.Many2one('ir.logging', string='Log', readonly=True)
|
||||
name = fields.Char(string='Module', readonly=True)
|
||||
message = fields.Text(string='Message', readonly=True)
|
||||
summary = fields.Text(string='Summary', readonly=True)
|
||||
log_type = fields.Char(string='Type', readonly=True)
|
||||
log_create_date = fields.Datetime(string='Log create date', readonly=True)
|
||||
func = fields.Char(string='Method', readonly=True)
|
||||
path = fields.Char(string='Path', readonly=True)
|
||||
line = fields.Char(string='Line', readonly=True)
|
||||
build_id = fields.Many2one('runbot.build', string='Build', readonly=True)
|
||||
bu_name = fields.Char(String='Build name', readonly=True)
|
||||
dest = fields.Char(String='Build dest', readonly=True)
|
||||
local_state = fields.Char(string='Local state', readonly=True)
|
||||
local_result = fields.Char(string='Local result', readonly=True)
|
||||
global_state = fields.Char(string='Global state', readonly=True)
|
||||
global_result = fields.Char(string='Global result', readonly=True)
|
||||
bu_create_date = fields.Datetime(string='Build create date', readonly=True)
|
||||
committer = fields.Char(string='committer', readonly=True)
|
||||
author = fields.Char(string='Author', readonly=True)
|
||||
host = fields.Char(string='Host', readonly=True)
|
||||
config_id = fields.Many2one('runbot.build.config', string='Config', readonly=True)
|
||||
parent_id = fields.Many2one('runbot.build', string='Parent build', readonly=True)
|
||||
hidden = fields.Boolean(string='Hidden', readonly=True)
|
||||
branch_id = fields.Many2one('runbot.branch', string='Branch', readonly=True)
|
||||
branch_name = fields.Char(string='Branch name', readonly=True)
|
||||
repo_id = fields.Many2one('runbot.repo', string='Repo', readonly=True)
|
||||
repo_name = fields.Char(string='Repo name', readonly=True)
|
||||
repo_short_name = fields.Char(compute='_compute_repo_short_name', readonly=True)
|
||||
build_url = fields.Char(compute='_compute_build_url', readonly=True)
|
||||
|
||||
def _compute_repo_short_name(self):
|
||||
for l in self:
|
||||
l.repo_short_name = '/'.join(l.repo_id.base.split('/')[-2:])
|
||||
|
||||
def _compute_build_url(self):
|
||||
for l in self:
|
||||
l.build_url = '/runbot/build/%s' % l.build_id.id
|
||||
|
||||
def action_goto_build(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
"type": "ir.actions.act_url",
|
||||
"url": "runbot/build/%s" % self.build_id.id,
|
||||
"target": "new",
|
||||
}
|
||||
|
||||
@api.model_cr
|
||||
def init(self):
|
||||
""" Create an SQL view for ir.logging """
|
||||
tools.drop_view_if_exists(self._cr, 'runbot_error_log')
|
||||
self._cr.execute(""" CREATE VIEW runbot_error_log AS (
|
||||
SELECT
|
||||
l.id AS id,
|
||||
l.name AS name,
|
||||
l.message AS message,
|
||||
left(l.message, 50) as summary,
|
||||
l.type AS log_type,
|
||||
l.create_date AS log_create_date,
|
||||
l.func AS func,
|
||||
l.path AS path,
|
||||
l.line AS line,
|
||||
bu.id AS build_id,
|
||||
bu.name AS bu_name,
|
||||
bu.dest AS dest,
|
||||
bu.local_state AS local_state,
|
||||
bu.local_result AS local_result,
|
||||
bu.global_state AS global_state,
|
||||
bu.global_result AS global_result,
|
||||
bu.create_date AS bu_create_date,
|
||||
bu.committer AS committer,
|
||||
bu.author AS author,
|
||||
bu.host AS host,
|
||||
bu.config_id AS config_id,
|
||||
bu.parent_id AS parent_id,
|
||||
bu.hidden AS hidden,
|
||||
br.id AS branch_id,
|
||||
br.branch_name AS branch_name,
|
||||
re.id AS repo_id,
|
||||
re.name AS repo_name
|
||||
FROM
|
||||
ir_logging AS l
|
||||
JOIN
|
||||
runbot_build bu ON l.build_id = bu.id
|
||||
JOIN
|
||||
runbot_branch br ON br.id = bu.branch_id
|
||||
JOIN
|
||||
runbot_repo re ON br.repo_id = re.id
|
||||
WHERE
|
||||
l.level = 'ERROR'
|
||||
)""")
|
||||
|
@ -27,4 +27,7 @@ access_runbot_error_regex_user,runbot_error_regex_user,runbot.model_runbot_error
|
||||
access_runbot_error_regex_manager,runbot_error_regex_manager,runbot.model_runbot_error_regex,runbot.group_runbot_admin,1,1,1,1
|
||||
|
||||
access_runbot_host_user,runbot_host_user,runbot.model_runbot_host,group_user,1,0,0,0
|
||||
access_runbot_host_manager,runbot_host_manager,runbot.model_runbot_host,runbot.group_runbot_admin,1,1,1,1
|
||||
access_runbot_host_manager,runbot_host_manager,runbot.model_runbot_host,runbot.group_runbot_admin,1,1,1,1
|
||||
|
||||
access_runbot_error_log_user,runbot_error_log_user,runbot.model_runbot_error_log,group_user,1,0,0,0
|
||||
access_runbot_error_log_manager,runbot_error_log_manager,runbot.model_runbot_error_log,runbot.group_runbot_admin,1,1,1,1
|
|
103
runbot/views/error_log_views.xml
Normal file
103
runbot/views/error_log_views.xml
Normal file
@ -0,0 +1,103 @@
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="runbot_error_log_form_view" model="ir.ui.view">
|
||||
<field name="name">Runbot Error Log form view</field>
|
||||
<field name="model">runbot.error.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Build Error">
|
||||
|
||||
|
||||
<header>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1><field name="build_id"/></h1>
|
||||
<field name="build_url" widget="url"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="repo_short_name"/>
|
||||
<field name="branch_name"/>
|
||||
<field name="log_type"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="func"/>
|
||||
<field name="path"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Log message" name="log_message">
|
||||
<group>
|
||||
<field name="message"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_error_log_tree_view" model="ir.ui.view">
|
||||
<field name="name">Runbot Error Log tree view</field>
|
||||
<field name="model">runbot.error.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Build Errors">
|
||||
<button name="action_goto_build" type="object" icon="fa-external-link "/>
|
||||
<field name="build_id"/>
|
||||
<field name="log_create_date"/>
|
||||
<field name="repo_short_name"/>
|
||||
<field name="branch_name"/>
|
||||
<field name="name"/>
|
||||
<field name="func"/>
|
||||
<field name="path"/>
|
||||
<field name="summary"/>
|
||||
<field name="log_type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="runbot_logs_search_view" model="ir.ui.view">
|
||||
<field name="name">runbot.error.log.filter</field>
|
||||
<field name="model">runbot.error.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search master">
|
||||
<field name="message"/>
|
||||
<field name="name" string="Module"/>
|
||||
<field name="func"/>
|
||||
<field name="branch_name"/>
|
||||
<field name="repo_name"/>
|
||||
<field name="build_id"/>
|
||||
<filter string="Failed builds" name="failed_builds" domain="[('global_state', '=', 'done'), ('global_result', '=', 'ko')]"/>
|
||||
<separator/>
|
||||
<filter string="Master branches" name="master_branches" domain="[('branch_name', '=', 'master')]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_view_error_log_tree" model="ir.actions.act_window">
|
||||
<field name="name">Error Logs</field>
|
||||
<field name="res_model">runbot.error.log</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_master_branches': True, 'search_default_failed_builds': True}</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="runbot_log_menu"
|
||||
name="Logs"
|
||||
parent="runbot_menu_root"
|
||||
sequence="50"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
name="Error Logs"
|
||||
id="runbot_menu_error_logs"
|
||||
parent="runbot_log_menu"
|
||||
sequence="20"
|
||||
action="open_view_error_log_tree"
|
||||
/>
|
||||
</data>
|
||||
</odoo>
|
Loading…
Reference in New Issue
Block a user