Check-in [d3dbeea9f5]
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Basic error-to-ticket conversion backend. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d3dbeea9f57ba636720f116b08fcc6b8 |
User & Date: | mario 2021-04-14 07:22:56 |
Context
2021-09-05
| ||
06:50 | shorthand $EDITOR for wiki pages check-in: 7dc5402ce6 user: mario tags: trunk | |
2021-04-14
| ||
07:22 | Basic error-to-ticket conversion backend. check-in: d3dbeea9f5 user: mario tags: trunk | |
2021-04-10
| ||
22:47 | Workaround for Content-Location: header, add h: and -cap: attrs, fix [scope] unwrapping, accept mime types, refold properties[] into strings, correct error type for invalid token. check-in: dd450f3109 user: mario tags: trunk | |
Changes
Added extroot/crashreport.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #!/usr/bin/php-cgi -dcgi.force_redirect=0 <?php # encoding: utf-8 # api: cgi # type: api # category: tickets # title: Crashreport # description: Receives errors (JSON POST) and files them as tickets # version: 0.1 # state: alpha # config: - # # Creates a ticket for any POST it receives that contains valid JSON. # Unpacks some fields into ticket properties, and posts the whole blob # as ticket comment. This is probably more suitable for GUI apps than # smaller console tools or librarikes. # And it could probably also be reused for storing feature requests. # # Now this has some privacy implications. So care should be taken which # information is included, the filter options expanded, or perhaps even # the ticket backend taken non-public. # # Basic usage could be something like: # # catch Exception as e: # import requests, traceback, json # requests.post("http://fossil.example.com/repo/ext/crashreport", data=json.dumps({ # "version": "0.0.1", # "file": __file__, # "error": str(e), # "exception": repr(e), # "backtrace": traceback.extract_tb, # "locals": locals(), # }, default=lambda v: repr(v))) # # Obviously you might want to wrap this in some general reporting call. # And certainly customize the mapping for actually used fields. #-- config # require that POST payload contains at least one of those fields (to avert arbitrary spambots filing tickets) $required_fields = [ "version", "error", "exception", ]; # contained fields onto ticket properties $map_fields = [ "error" => "title", "version" => "foundin", "module" => "subsystem", ]; # ticket defaults $default_fields = [ #"comment" => "JSON", #"foundin" => "0.0.1", #"icomment" => "". #"login" => "extroot", "mimetype" => "text/json", "private_contact" => "", "type" => "Incident", "status" => "Open", "severity" => "Medium", "priority" => "Medium", #"resolution" => "", "subsystem" => "core", "title" => "Crashreport", "username" => "crashreport", ]; # rewrite text contents in any field (some privacy filtering) $filter_content = [ "~/home/[\w\-\.]+/~" => "/home/user/", # avoid user names "~[^\\t\\r\\n\\x20-\\xFF]/~" => "#", # no control chars ]; #-- init if ($_SERVER["CONTENT_LENGTH"] >= 10) { $json = from_input(); if (!array_intersect(array_keys($json), $required_fields)) { die(json_encode(["error" => "required fields missing"])); } store($json); } else { header("Content-Type: text/x-markdown"); die("Save any stacktraces/errors/etc. as tickets, if sent as JSON blob per POST."); } # assume input is JSON function from_input() { return json_decode(file_get_contents("php://input"), True); } # store as ticket function store($data) { global $map_fields, $default_fields, $filter_content; #-- prepare fields $fields = $default_fields; $fields["comment"] = json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); #-- extra fields foreach ($map_fields as $from=>$to) { if (isset($data[$from])) { $fields[$to] = substr($data[$from], 0, 100); } } #-- assemble cmd $cmd = "fossil --nocgi -R {$q($_SERVER['FOSSIL_REPOSITORY'])} ticket add"; $q = 'escapeshellarg'; foreach ($fields as $name=>$value) { foreach ($filter_content as $rx=>$to) { $value = preg_replace($rx, $to, $value); } $cmd .= " {$q($name)} {$q($value)}"; } #-- run exec($cmd, $stdout, $errno); #-- JSON response if (!$errno) { die(json_encode(["error" => $stdout, "errno" => $errno])); } else { die(json_encode(["success" => $stdout, "errno" => $errno])); } } |