def __getattr__(self, name): if name == 'site': return Site.get_name_by_id(self.envid, self.site_id) elif name == 'project': return Project.get_name_by_id(self.envid, self.project_id) raise AttributeError(name)
def gen(self, key, data=None, userid=None, site_id=None, timestamp=None): # pylint: disable=too-many-arguments # pylint: disable=too-many-locals # pylint: disable=too-many-statements # pylint: disable=too-many-branches """Generate an event. Arguments: key: The key to look up. data: A Dictionary with all of the event information. Recognized keys: - From http response: stdout stderr xid pid exit-status run-status timestamp - Sometimes added: error info - Available from AgentConnection: displayname agent_type uuid auth, which has: hostname ip-address version listen-port install-dir """ if data == None: data = {} if 'enabled' in data and not data['enabled']: logger.debug("Agent is disabled so no event will be " + \ "generated. key: %s, data: %s", key, data) return event_entry = self.get_event_control_entry(key) if event_entry: subject = event_entry.subject event_description = event_entry.event_description else: logger.error("No such event key: %s. data: %s\n", key, str(data)) return # add all system table entries to the data dictionary. data = dict(data.items() + \ self.system.todict(include_defaults=True).items()) logger.debug(key + " DATA: " + str(data)) if 'exit-status' in data: data['exit_status'] = data['exit-status'] del data['exit-status'] # FIXME: remove when browser-aware timezone support is available. if timestamp is None: timestamp = datetime.datetime.now(tz=tz.tzlocal()) logger.debug(key + " timestamp : " + timestamp.strftime(DATEFMT)) data['timestamp'] = timestamp.strftime(DATEFMT) # The userid for other events is the Palette "userid". profile = None if not 'username' in data and userid != None: profile = UserProfile.get(self.envid, userid) if not profile is None: data['username'] = profile.display_name() data['userid'] = profile.userid if profile.email: data['email'] = profile.email if userid: # userid passed to us has higher precedence than any # lookup we did, above. data['userid'] = userid if not 'username' in data: data['username'] = mako.runtime.UNDEFINED data['event_type'] = event_entry.event_type data['event_type_label'] = event_entry.event_type_label data['event_label'] = event_entry.event_label data['event_label_desc'] = event_entry.event_label_desc data['admin_visibility'] = event_entry.admin_visibility data['publisher_visiblity'] = event_entry.publisher_visibility # set server-url(s) data['server_url'] = self.system[SystemKeys.SERVER_URL] url = self.server.public_url() if url: data['tableau_server_url'] = url if not 'environment' in data: data['environment'] = self.server.environment.name if 'site_id' in data and 'site' not in data: site = Site.get_name_by_id(self.envid, data['site_id']) if not site is None: data['site'] = site if 'project_id' in data and 'project' not in data: project = Project.get_name_by_id(self.envid, data['project_id']) if not project is None: data['project'] = project # Create the row to get the eventid before doing subject/description # substitution. session = meta.DBSession() entry = EventEntry(complete=False, key='incomplete') # set the timestamp here in case it has tzinfo. entry.timestamp = timestamp session.add(entry) session.commit() data['eventid'] = entry.eventid # Use the data dict for template substitution. try: subject = subject % data except (ValueError, KeyError) as ex: subject = "Template subject conversion failure: " + str(ex) + \ "subject: " + subject + \ ", data: " + str(data) if event_description: try: mako_template = Template(event_description, default_filters=['h']) event_description = mako_template.render(**data) except MakoException: event_description = \ "Mako template message conversion failure: " + \ exceptions.text_error_template().render() + \ "\ntemplate: " + event_description + \ "\ndata: " + str(data) except TypeError as ex: event_description = \ "Mako template message conversion failure: " + \ str(ex) + \ "\ntemplate: " + event_description + \ "\ndata: " + str(data) else: event_description = self.make_default_description(data) event_description = re.sub("(\n|\r\n){3,}", "\n\n", event_description) if not event_description.endswith("\n"): event_description = event_description + "\n" if self.server.event_debug: event_description = event_description + "--------\n" + str(data) # FIXME: remove when browser-aware timezone support is available. if timestamp.tzinfo is None: # if not timezone is specified, assume UTC. summary = utc2local(timestamp).strftime(DATEFMT) else: summary = timestamp.strftime(DATEFMT) # Log the event to the database entry.complete = True entry.key = key entry.envid = self.envid entry.title = subject entry.description = event_description entry.level = event_entry.level entry.icon = event_entry.icon entry.color = event_entry.color entry.event_type = event_entry.event_type entry.summary = summary entry.userid = userid entry.site_id = site_id #entry.timestamp = timestamp session.merge(entry) session.commit() if not event_entry.send_email: return try: self.alert_email.send(event_entry, data, eventid=entry.eventid) except StandardError: exc_traceback = sys.exc_info()[2] tback = ''.join(traceback.format_tb(exc_traceback)) report = "Error: %s. Traceback: %s" % (sys.exc_info()[1], tback) logger.error( "alert_email: Failed for event '%s', '" "data '%s'. Will not send email. %s", event_entry.key, str(data), report)