slow_call.py
127 lines
| 4.7 KiB
| text/x-python
|
PythonLexer
r0 | # -*- coding: utf-8 -*- | |||
r112 | # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors | |||
r0 | # | |||
r112 | # Licensed under the Apache License, Version 2.0 (the "License"); | |||
# you may not use this file except in compliance with the License. | ||||
# You may obtain a copy of the License at | ||||
r0 | # | |||
r112 | # http://www.apache.org/licenses/LICENSE-2.0 | |||
r0 | # | |||
r112 | # Unless required by applicable law or agreed to in writing, software | |||
# distributed under the License is distributed on an "AS IS" BASIS, | ||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
# See the License for the specific language governing permissions and | ||||
# limitations under the License. | ||||
r0 | ||||
import sqlalchemy as sa | ||||
import hashlib | ||||
from datetime import datetime, timedelta | ||||
from appenlight.models import Base | ||||
from sqlalchemy.dialects.postgresql import JSON | ||||
from ziggurat_foundations.models.base import BaseModel | ||||
class SlowCall(Base, BaseModel): | ||||
r153 | __tablename__ = "slow_calls" | |||
__table_args__ = {"implicit_returning": False} | ||||
r0 | ||||
resource_id = sa.Column(sa.Integer(), nullable=False, index=True) | ||||
id = sa.Column(sa.Integer, nullable=False, primary_key=True) | ||||
r153 | report_id = sa.Column( | |||
sa.BigInteger, | ||||
sa.ForeignKey("reports.id", ondelete="cascade", onupdate="cascade"), | ||||
primary_key=True, | ||||
) | ||||
r0 | duration = sa.Column(sa.Float(), default=0) | |||
r153 | statement = sa.Column(sa.UnicodeText(), default="") | |||
statement_hash = sa.Column(sa.Unicode(60), default="") | ||||
r0 | parameters = sa.Column(JSON(), nullable=False, default=dict) | |||
r153 | type = sa.Column(sa.Unicode(16), default="") | |||
r0 | subtype = sa.Column(sa.Unicode(16), default=None) | |||
r153 | location = sa.Column(sa.Unicode(255), default="") | |||
timestamp = sa.Column( | ||||
sa.DateTime(), default=datetime.utcnow, server_default=sa.func.now() | ||||
) | ||||
report_group_time = sa.Column( | ||||
sa.DateTime(), default=datetime.utcnow, server_default=sa.func.now() | ||||
) | ||||
r0 | ||||
r153 | def set_data( | |||
self, data, protocol_version=None, resource_id=None, report_group=None | ||||
): | ||||
r0 | self.resource_id = resource_id | |||
r153 | if data.get("start") and data.get("end"): | |||
self.timestamp = data.get("start") | ||||
d = data.get("end") - data.get("start") | ||||
r0 | self.duration = d.total_seconds() | |||
r153 | self.statement = data.get("statement", "") | |||
self.type = data.get("type", "unknown")[:16] | ||||
self.parameters = data.get("parameters", {}) | ||||
self.location = data.get("location", "")[:255] | ||||
r0 | self.report_group_time = report_group.first_timestamp | |||
r153 | if "subtype" in data: | |||
self.subtype = data.get("subtype", "unknown")[:16] | ||||
if self.type == "tmpl": | ||||
self.set_hash("{} {}".format(self.statement, self.parameters)) | ||||
r0 | else: | |||
self.set_hash() | ||||
def set_hash(self, custom_statement=None): | ||||
statement = custom_statement or self.statement | ||||
r153 | self.statement_hash = hashlib.sha1(statement.encode("utf8")).hexdigest() | |||
r0 | ||||
@property | ||||
def end_time(self): | ||||
if self.duration and self.timestamp: | ||||
return self.timestamp + timedelta(seconds=self.duration) | ||||
return None | ||||
def get_dict(self): | ||||
instance_dict = super(SlowCall, self).get_dict() | ||||
r153 | instance_dict["children"] = [] | |||
instance_dict["end_time"] = self.end_time | ||||
r0 | return instance_dict | |||
def es_doc(self): | ||||
doc = { | ||||
r153 | "resource_id": self.resource_id, | |||
"timestamp": self.timestamp, | ||||
"pg_id": str(self.id), | ||||
"permanent": False, | ||||
"request_id": None, | ||||
"log_level": "UNKNOWN", | ||||
"message": self.statement, | ||||
"namespace": "appenlight.slow_call", | ||||
"tags": { | ||||
"report_id": { | ||||
"values": self.report_id, | ||||
"numeric_values": self.report_id, | ||||
}, | ||||
"duration": {"values": None, "numeric_values": self.duration}, | ||||
"statement_hash": { | ||||
"values": self.statement_hash, | ||||
"numeric_values": None, | ||||
}, | ||||
"type": {"values": self.type, "numeric_values": None}, | ||||
"subtype": {"values": self.subtype, "numeric_values": None}, | ||||
"location": {"values": self.location, "numeric_values": None}, | ||||
"parameters": {"values": None, "numeric_values": None}, | ||||
r0 | }, | |||
r153 | "tag_list": [ | |||
"report_id", | ||||
"duration", | ||||
"statement_hash", | ||||
"type", | ||||
"subtype", | ||||
"location", | ||||
], | ||||
r0 | } | |||
if isinstance(self.parameters, str): | ||||
r153 | doc["tags"]["parameters"]["values"] = self.parameters[:255] | |||
r0 | return doc | |||
@property | ||||
def partition_id(self): | ||||
r153 | return "rcae_sc_%s" % self.report_group_time.strftime("%Y_%m") | |||