Support for stacked profiler analysis

This commit is contained in:
Michael 2021-07-27 04:57:29 +00:00
parent 3cef3ab107
commit c89533a70b
17 changed files with 763 additions and 611 deletions

View file

@ -22,7 +22,6 @@
use Friendica\App;
use Friendica\Content\ContactSelector;
use Friendica\Content\Feature;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
@ -34,7 +33,6 @@ use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Profile;
use Friendica\Model\Tag;
use Friendica\Model\Verb;
use Friendica\Object\Post as PostObject;
@ -56,6 +54,7 @@ use Friendica\Util\XML;
*/
function localize_item(&$item)
{
DI::profiler()->startRecording('rendering');
/// @todo The following functionality needs to be cleaned up.
if (!empty($item['verb'])) {
$activity = DI::activity();
@ -65,9 +64,11 @@ function localize_item(&$item)
if (stristr($item['verb'], Activity::POKE)) {
$verb = urldecode(substr($item['verb'], strpos($item['verb'],'#') + 1));
if (!$verb) {
DI::profiler()->stopRecording();
return;
}
if ($item['object-type'] == "" || $item['object-type'] !== Activity\ObjectType::PERSON) {
DI::profiler()->stopRecording();
return;
}
@ -120,6 +121,7 @@ function localize_item(&$item)
'verb', 'object-type', 'resource-id', 'body', 'plink'];
$obj = Post::selectFirst($fields, ['uri' => $item['parent-uri']]);
if (!DBA::isResult($obj)) {
DI::profiler()->stopRecording();
return;
}
@ -177,6 +179,7 @@ function localize_item(&$item)
'network' => $item['author-network'], 'url' => $item['author-link']];
$item['plink'] = Contact::magicLinkByContact($author, $item['plink']);
}
DI::profiler()->stopRecording();
}
/**
@ -263,6 +266,7 @@ function conv_get_blocklist()
*/
function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
{
DI::profiler()->startRecording('rendering');
$page = DI::page();
$page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js'));
@ -603,6 +607,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
'$dropping' => ($page_dropping ? DI::l10n()->t('Delete Selected Items') : False),
]);
DI::profiler()->stopRecording();
return $o;
}
@ -616,6 +621,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
* @return array items with parents and comments
*/
function conversation_fetch_comments($thread_items, bool $pinned, array $activity) {
DI::profiler()->startRecording('rendering');
$comments = [];
while ($row = Post::fetch($thread_items)) {
@ -693,6 +699,7 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
DBA::close($thread_items);
DI::profiler()->stopRecording();
return $comments;
}
@ -711,6 +718,7 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function conversation_add_children(array $parents, $block_authors, $order, $uid) {
DI::profiler()->startRecording('rendering');
if (count($parents) > 1) {
$max_comments = DI::config()->get('system', 'max_comments', 100);
} else {
@ -753,6 +761,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
$items = conv_sort($items, $order);
DI::profiler()->stopRecording();
return $items;
}
@ -768,6 +777,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
* @return array
*/
function conversation_fetch_items(array $parent, array $items, array $condition, bool $block_authors, array $params, array $activity) {
DI::profiler()->startRecording('rendering');
if ($block_authors) {
$condition[0] .= " AND NOT `author-hidden`";
}
@ -779,11 +789,13 @@ function conversation_fetch_items(array $parent, array $items, array $condition,
if (count($comments) != 0) {
$items = array_merge($items, $comments);
}
DI::profiler()->stopRecording();
return $items;
}
function item_photo_menu($item)
{
DI::profiler()->startRecording('rendering');
$sub_link = '';
$poke_link = '';
$contact_url = '';
@ -882,6 +894,7 @@ function item_photo_menu($item)
$o .= '<li role="menuitem"><a href="' . $v . '">' . $k . '</a></li>' . PHP_EOL;
}
}
DI::profiler()->stopRecording();
return $o;
}
@ -980,6 +993,7 @@ function builtin_activity_puller(array $activity, array &$conv_responses)
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
function format_activity(array $links, $verb, $id) {
DI::profiler()->startRecording('rendering');
$o = '';
$expanded = '';
$phrase = '';
@ -1059,11 +1073,13 @@ function format_activity(array $links, $verb, $id) {
]);
$o .= $expanded;
DI::profiler()->stopRecording();
return $o;
}
function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
{
DI::profiler()->startRecording('rendering');
$o = '';
$geotag = !empty($x['allow_location']) ? Renderer::replaceMacros(Renderer::getMarkupTemplate('jot_geotag.tpl'), []) : '';
@ -1151,6 +1167,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
$o = '<div id="jot-popup" style="display: none;">' . $o . '</div>';
}
DI::profiler()->stopRecording();
return $o;
}
@ -1164,6 +1181,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
*/
function get_item_children(array &$item_list, array $parent, $recursive = true)
{
DI::profiler()->startRecording('rendering');
$children = [];
foreach ($item_list as $i => $item) {
if ($item['gravity'] != GRAVITY_PARENT) {
@ -1185,6 +1203,7 @@ function get_item_children(array &$item_list, array $parent, $recursive = true)
}
}
}
DI::profiler()->stopRecording();
return $children;
}
@ -1196,6 +1215,7 @@ function get_item_children(array &$item_list, array $parent, $recursive = true)
*/
function sort_item_children(array $items)
{
DI::profiler()->startRecording('rendering');
$result = $items;
usort($result, 'sort_thr_received_rev');
foreach ($result as $k => $i) {
@ -1203,6 +1223,7 @@ function sort_item_children(array $items)
$result[$k]['children'] = sort_item_children($result[$k]['children']);
}
}
DI::profiler()->stopRecording();
return $result;
}
@ -1240,7 +1261,9 @@ function add_children_to_list(array $children, array &$item_list)
*/
function smart_flatten_conversation(array $parent)
{
DI::profiler()->startRecording('rendering');
if (!isset($parent['children']) || count($parent['children']) == 0) {
DI::profiler()->stopRecording();
return $parent;
}
@ -1251,6 +1274,7 @@ function smart_flatten_conversation(array $parent)
if (isset($child['children']) && count($child['children'])) {
// This helps counting only the regular posts
$count_post_closure = function($var) {
DI::profiler()->stopRecording();
return $var['verb'] === Activity::POST;
};
@ -1276,6 +1300,7 @@ function smart_flatten_conversation(array $parent)
}
}
DI::profiler()->stopRecording();
return $parent;
}
@ -1293,9 +1318,11 @@ function smart_flatten_conversation(array $parent)
*/
function conv_sort(array $item_list, $order)
{
DI::profiler()->startRecording('rendering');
$parents = [];
if (!(is_array($item_list) && count($item_list))) {
DI::profiler()->stopRecording();
return $parents;
}
@ -1355,6 +1382,7 @@ function conv_sort(array $item_list, $order)
}
}
DI::profiler()->stopRecording();
return $parents;
}

View file

@ -152,6 +152,7 @@ class BBCode
*/
public static function getAttachmentData($body)
{
DI::profiler()->startRecording('rendering');
$data = [
'type' => '',
'text' => '',
@ -167,6 +168,7 @@ class BBCode
];
if (!preg_match("/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism", $body, $match)) {
DI::profiler()->stopRecording();
return self::getOldAttachmentData($body);
}
@ -211,6 +213,7 @@ class BBCode
}
if (!in_array($data['type'], ['link', 'audio', 'photo', 'video'])) {
DI::profiler()->stopRecording();
return [];
}
@ -232,6 +235,7 @@ class BBCode
}
}
DI::profiler()->stopRecording();
return $data;
}
@ -247,6 +251,7 @@ class BBCode
- (thumbnail)
*/
DI::profiler()->startRecording('rendering');
$has_title = !empty($item['title']);
$plink = $item['plink'] ?? '';
$post = self::getAttachmentData($body);
@ -398,6 +403,7 @@ class BBCode
}
}
DI::profiler()->stopRecording();
return $post;
}
@ -434,6 +440,7 @@ class BBCode
*/
public static function toPlaintext($text, $keep_urls = true)
{
DI::profiler()->startRecording('rendering');
// Remove pictures in advance to avoid unneeded proxy calls
$text = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $2 ', $text);
$text = preg_replace("/\[img.*?\[\/img\]/ism", ' ', $text);
@ -443,6 +450,7 @@ class BBCode
$naked_text = HTML::toPlaintext(self::convert($text, false, 0, true), 0, !$keep_urls);
DI::profiler()->stopRecording();
return $naked_text;
}
@ -468,6 +476,7 @@ class BBCode
*/
public static function scaleExternalImages(string $srctext)
{
DI::profiler()->startRecording('rendering');
$s = $srctext;
// Simplify image links
@ -517,6 +526,7 @@ class BBCode
}
}
DI::profiler()->stopRecording();
return $s;
}
@ -532,6 +542,7 @@ class BBCode
*/
public static function limitBodySize($body)
{
DI::profiler()->startRecording('rendering');
$maxlen = DI::config()->get('config', 'max_import_size', 0);
// If the length of the body, including the embedded images, is smaller
@ -603,8 +614,10 @@ class BBCode
$new_body = $new_body . $orig_body;
}
DI::profiler()->stopRecording();
return $new_body;
} else {
DI::profiler()->stopRecording();
return $body;
}
}
@ -624,13 +637,13 @@ class BBCode
*/
public static function convertAttachment($text, $simplehtml = self::INTERNAL, $tryoembed = true, array $data = [], $uriid = 0)
{
DI::profiler()->startRecording('rendering');
$data = $data ?: self::getAttachmentData($text);
if (empty($data) || empty($data['url'])) {
DI::profiler()->stopRecording();
return $text;
}
$stamp1 = microtime(true);
if (isset($data['title'])) {
$data['title'] = strip_tags($data['title']);
$data['title'] = str_replace(['http://', 'https://'], '', $data['title']);
@ -688,17 +701,20 @@ class BBCode
}
}
DI::profiler()->saveTimestamp($stamp1, 'rendering');
DI::profiler()->stopRecording();
return trim(($data['text'] ?? '') . ' ' . $return . ' ' . ($data['after'] ?? ''));
}
public static function removeShareInformation($Text, $plaintext = false, $nolink = false)
{
DI::profiler()->startRecording('rendering');
$data = self::getAttachmentData($Text);
if (!$data) {
DI::profiler()->stopRecording();
return $Text;
} elseif ($nolink) {
DI::profiler()->stopRecording();
return $data['text'] . ($data['after'] ?? '');
}
@ -712,11 +728,13 @@ class BBCode
}
if (empty($data['text']) && !empty($data['title']) && empty($data['url'])) {
DI::profiler()->stopRecording();
return $data['title'] . $data['after'];
}
// If the link already is included in the post, don't add it again
if (!empty($data['url']) && strpos($data['text'], $data['url'])) {
DI::profiler()->stopRecording();
return $data['text'] . $data['after'];
}
@ -728,6 +746,7 @@ class BBCode
$text .= "\n[url]" . $data['url'] . '[/url]';
}
DI::profiler()->stopRecording();
return $text . "\n" . $data['after'];
}
@ -821,6 +840,7 @@ class BBCode
*/
public static function getTagPosition($text, $name, $occurrences = 0)
{
DI::profiler()->startRecording('rendering');
if ($occurrences < 0) {
$occurrences = 0;
}
@ -833,6 +853,7 @@ class BBCode
}
if ($start_open === false) {
DI::profiler()->stopRecording();
return false;
}
@ -840,6 +861,7 @@ class BBCode
$start_close = strpos($text, ']', $start_open);
if ($start_close === false) {
DI::profiler()->stopRecording();
return false;
}
@ -848,6 +870,7 @@ class BBCode
$end_open = strpos($text, '[/' . $name . ']', $start_close);
if ($end_open === false) {
DI::profiler()->stopRecording();
return false;
}
@ -866,6 +889,7 @@ class BBCode
$res['start']['equal'] = $start_equal + 1;
}
DI::profiler()->stopRecording();
return $res;
}
@ -880,6 +904,7 @@ class BBCode
*/
public static function pregReplaceInTag($pattern, $replace, $name, $text)
{
DI::profiler()->startRecording('rendering');
$occurrences = 0;
$pos = self::getTagPosition($text, $name, $occurrences);
while ($pos !== false && $occurrences++ < 1000) {
@ -896,6 +921,7 @@ class BBCode
$pos = self::getTagPosition($text, $name, $occurrences);
}
DI::profiler()->stopRecording();
return $text;
}
@ -964,12 +990,14 @@ class BBCode
*/
public static function fetchShareAttributes($text)
{
DI::profiler()->startRecording('rendering');
// See Issue https://github.com/friendica/friendica/issues/10454
// Hashtags in usernames are expanded to links. This here is a quick fix.
$text = preg_replace('/([@!#])\[url\=.*?\](.*?)\[\/url\]/ism', '$1$2', $text);
$attributes = [];
if (!preg_match("/(.*?)\[share(.*?)\](.*)\[\/share\]/ism", $text, $matches)) {
DI::profiler()->stopRecording();
return $attributes;
}
@ -978,6 +1006,7 @@ class BBCode
preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
$attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
}
DI::profiler()->stopRecording();
return $attributes;
}
@ -1002,6 +1031,7 @@ class BBCode
*/
public static function convertShare($text, callable $callback, int $uriid = 0)
{
DI::profiler()->startRecording('rendering');
$return = preg_replace_callback(
"/(.*?)\[share(.*?)\](.*)\[\/share\]/ism",
function ($match) use ($callback, $uriid) {
@ -1033,6 +1063,7 @@ class BBCode
$text
);
DI::profiler()->stopRecording();
return $return;
}
@ -1052,6 +1083,7 @@ class BBCode
*/
private static function convertShareCallback(array $attributes, array $author_contact, $content, $is_quote_share, $simplehtml)
{
DI::profiler()->startRecording('rendering');
$mention = Protocol::formatMention($attributes['profile'], $attributes['author']);
switch ($simplehtml) {
@ -1247,19 +1279,23 @@ class BBCode
public static function cleanPictureLinks($text)
{
DI::profiler()->startRecording('rendering');
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $return);
DI::profiler()->stopRecording();
return $return;
}
public static function removeLinks(string $bbcode)
{
DI::profiler()->startRecording('rendering');
$bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode);
$bbcode = preg_replace("/\[img.*?\[\/img\]/ism", ' ', $bbcode);
$bbcode = preg_replace('/[@!#]\[url\=.*?\].*?\[\/url\]/ism', '', $bbcode);
$bbcode = preg_replace("/\[url=[^\[\]]*\](.*)\[\/url\]/Usi", ' $1 ', $bbcode);
$bbcode = preg_replace('/[@!#]?\[url.*?\[\/url\]/ism', '', $bbcode);
DI::profiler()->stopRecording();
return $bbcode;
}
@ -1271,8 +1307,11 @@ class BBCode
*/
public static function setMentionsToNicknames(string $body):string
{
DI::profiler()->startRecording('rendering');
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
return preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
$body = preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
DI::profiler()->stopRecording();
return $body;
}
/**
@ -1360,6 +1399,8 @@ class BBCode
return '';
}
DI::profiler()->startRecording('rendering');
Hook::callAll('bbcode', $text);
$a = DI::app();
@ -1979,6 +2020,7 @@ class BBCode
);
$text = HTML::purify($text, $allowedIframeDomains);
DI::profiler()->stopRecording();
return trim($text);
}
@ -1991,9 +2033,11 @@ class BBCode
*/
public static function stripAbstract($text)
{
DI::profiler()->startRecording('rendering');
$text = preg_replace("/[\s|\n]*\[abstract\].*?\[\/abstract\][\s|\n]*/ism", '', $text);
$text = preg_replace("/[\s|\n]*\[abstract=.*?\].*?\[\/abstract][\s|\n]*/ism", '', $text);
DI::profiler()->stopRecording();
return $text;
}
@ -2006,6 +2050,7 @@ class BBCode
*/
public static function getAbstract($text, $addon = '')
{
DI::profiler()->startRecording('rendering');
$abstract = '';
$abstracts = [];
$addon = strtolower($addon);
@ -2024,6 +2069,7 @@ class BBCode
$abstract = $result[1];
}
DI::profiler()->stopRecording();
return $abstract;
}
@ -2062,6 +2108,7 @@ class BBCode
*/
public static function toMarkdown($text, $for_diaspora = true)
{
DI::profiler()->startRecording('rendering');
$original_text = $text;
// Since Diaspora is creating a summary for links, this function removes them before posting
@ -2106,13 +2153,9 @@ class BBCode
// Maybe we should make this newline at every time before a quote.
$text = str_replace(['</a><blockquote>'], ['</a><br><blockquote>'], $text);
$stamp1 = microtime(true);
// Now convert HTML to Markdown
$text = HTML::toMarkdown($text);
DI::profiler()->saveTimestamp($stamp1, "parser");
// Libertree has a problem with escaped hashtags.
$text = str_replace(['\#'], ['#'], $text);
@ -2131,6 +2174,7 @@ class BBCode
Hook::callAll('bb2diaspora', $text);
DI::profiler()->stopRecording();
return $text;
}
@ -2149,6 +2193,7 @@ class BBCode
*/
public static function getTags($string)
{
DI::profiler()->startRecording('rendering');
$ret = [];
self::performWithEscapedTags($string, ['noparse', 'pre', 'code', 'img'], function ($string) use (&$ret) {
@ -2199,6 +2244,7 @@ class BBCode
}
});
DI::profiler()->stopRecording();
return array_unique($ret);
}
@ -2258,6 +2304,7 @@ class BBCode
*/
public static function setMentions($body, $profile_uid = 0, $network = '')
{
DI::profiler()->startRecording('rendering');
self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) {
$tags = self::getTags($body);
@ -2289,6 +2336,7 @@ class BBCode
return $body;
});
DI::profiler()->stopRecording();
return $body;
}
@ -2304,6 +2352,7 @@ class BBCode
*/
public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null)
{
DI::profiler()->startRecording('rendering');
$header = "[share author='" . str_replace(["'", "[", "]"], ["&#x27;", "&#x5B;", "&#x5D;"], $author) .
"' profile='" . str_replace(["'", "[", "]"], ["&#x27;", "&#x5B;", "&#x5D;"], $profile) .
"' avatar='" . str_replace(["'", "[", "]"], ["&#x27;", "&#x5B;", "&#x5D;"], $avatar) .
@ -2316,6 +2365,7 @@ class BBCode
$header .= "']";
DI::profiler()->stopRecording();
return $header;
}
@ -2337,6 +2387,7 @@ class BBCode
*/
public static function embedURL(string $url, bool $tryAttachment = true, string $title = null, string $description = null, string $tags = null): string
{
DI::profiler()->startRecording('rendering');
DI::logger()->info($url);
// If there is already some content information submitted we don't
@ -2358,6 +2409,7 @@ class BBCode
DI::logger()->info('(unparsed): returns: ' . $result);
DI::profiler()->stopRecording();
return $result;
}
@ -2376,6 +2428,7 @@ class BBCode
break;
}
DI::profiler()->stopRecording();
return $bbcode;
}
@ -2383,10 +2436,13 @@ class BBCode
// Bypass attachment if parse url for a comment
if (!$tryAttachment) {
DI::profiler()->stopRecording();
return "\n" . '[url=' . $url . ']' . $siteinfo['title'] . '[/url]';
}
// Format it as BBCode attachment
return "\n" . PageInfo::getFooterFromData($siteinfo);
$bbcode = "\n" . PageInfo::getFooterFromData($siteinfo);
DI::profiler()->stopRecording();
return $bbcode;
}
}

View file

@ -143,6 +143,7 @@ class HTML
*/
public static function toBBCode($message, $basepath = '')
{
DI::profiler()->startRecording('rendering');
$message = str_replace("\r", "", $message);
$message = Strings::performWithEscapedBlocks($message, '#<pre><code.*</code></pre>#iUs', function ($message) {
@ -396,6 +397,7 @@ class HTML
$message = self::qualifyURLs($message, $basepath);
}
DI::profiler()->stopRecording();
return $message;
}
@ -585,6 +587,7 @@ class HTML
*/
public static function toPlaintext(string $html, $wraplength = 75, $compact = false)
{
DI::profiler()->startRecording('rendering');
$message = str_replace("\r", "", $html);
$doc = new DOMDocument();
@ -593,6 +596,7 @@ class HTML
$message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
if (empty($message)) {
DI::profiler()->stopRecording();
return '';
}
@ -606,6 +610,7 @@ class HTML
$urls = self::collectURLs($message);
if (empty($message)) {
DI::profiler()->stopRecording();
return '';
}
@ -689,6 +694,7 @@ class HTML
$message = self::quoteLevel(trim($message), $wraplength);
DI::profiler()->stopRecording();
return trim($message);
}
@ -701,9 +707,11 @@ class HTML
*/
public static function toMarkdown($html)
{
DI::profiler()->startRecording('rendering');
$converter = new HtmlConverter(['hard_break' => true]);
$markdown = $converter->convert($html);
DI::profiler()->stopRecording();
return $markdown;
}

View file

@ -21,7 +21,6 @@
namespace Friendica\Content\Text;
use Friendica\Core\System;
use Friendica\DI;
use Friendica\Model\Contact;
@ -40,7 +39,7 @@ class Markdown
* @return string
*/
public static function convert($text, $hardwrap = true, $baseuri = null) {
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
$MarkdownParser = new MarkdownParser();
$MarkdownParser->code_class_prefix = 'language-';
@ -57,7 +56,7 @@ class Markdown
$html = $MarkdownParser->transform($text);
DI::profiler()->saveTimestamp($stamp1, "parser");
DI::profiler()->stopRecording();
return $html;
}
@ -109,6 +108,8 @@ class Markdown
*/
public static function toBBCode($s)
{
DI::profiler()->startRecording('rendering');
// The parser cannot handle paragraphs correctly
$s = str_replace(['</p>', '<p>', '<p dir="ltr">'], ['<br>', '<br>', '<br>'], $s);
@ -134,6 +135,7 @@ class Markdown
// Don't show link to full picture (until it is fixed)
$s = BBCode::scaleExternalImages($s);
DI::profiler()->stopRecording();
return $s;
}
}

View file

@ -236,9 +236,9 @@ class Addon
return $info;
}
$stamp1 = microtime(true);
DI::profiler()->startRecording('file');
$f = file_get_contents("addon/$addon/$addon.php");
DI::profiler()->saveTimestamp($stamp1, "file");
DI::profiler()->stopRecording();
$r = preg_match("|/\*.*\*/|msU", $f, $m);

View file

@ -52,11 +52,11 @@ class ProfilerCache implements ICache, IMemoryCache
*/
public function getAllKeys($prefix = null)
{
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->getAllKeys($prefix);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
}
@ -66,11 +66,11 @@ class ProfilerCache implements ICache, IMemoryCache
*/
public function get($key)
{
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->get($key);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
}
@ -80,11 +80,11 @@ class ProfilerCache implements ICache, IMemoryCache
*/
public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
{
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->set($key, $value, $ttl);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
}
@ -94,11 +94,11 @@ class ProfilerCache implements ICache, IMemoryCache
*/
public function delete($key)
{
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->delete($key);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
}
@ -108,11 +108,11 @@ class ProfilerCache implements ICache, IMemoryCache
*/
public function clear($outdated = true)
{
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->clear($outdated);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
}
@ -123,11 +123,11 @@ class ProfilerCache implements ICache, IMemoryCache
public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
{
if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->add($key, $value, $ttl);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
} else {
@ -141,11 +141,11 @@ class ProfilerCache implements ICache, IMemoryCache
public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES)
{
if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->compareSet($key, $oldValue, $newValue, $ttl);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
} else {
@ -159,11 +159,11 @@ class ProfilerCache implements ICache, IMemoryCache
public function compareDelete($key, $value)
{
if ($this->cache instanceof IMemoryCache) {
$time = microtime(true);
$this->profiler->startRecording('cache');
$return = $this->cache->compareDelete($key, $value);
$this->profiler->saveTimestamp($time, 'cache');
$this->profiler->stopRecording();
return $return;
} else {

View file

@ -73,7 +73,7 @@ class Renderer
*/
public static function replaceMacros(string $template, array $vars = [])
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
// pass $baseurl to all templates if it isn't set
$vars = array_merge(['$baseurl' => DI::baseUrl()->get(), '$APP' => DI::app()], $vars);
@ -90,7 +90,7 @@ class Renderer
throw new InternalServerErrorException($message);
}
DI::profiler()->saveTimestamp($stamp1, "rendering");
DI::profiler()->stopRecording();
return $output;
}
@ -106,7 +106,7 @@ class Renderer
*/
public static function getMarkupTemplate($file, $subDir = '')
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('file');
$t = self::getTemplateEngine();
try {
@ -119,7 +119,7 @@ class Renderer
throw new InternalServerErrorException($message);
}
DI::profiler()->saveTimestamp($stamp1, "file");
DI::profiler()->stopRecording();
return $template;
}

View file

@ -88,9 +88,9 @@ class Theme
return $info;
}
$stamp1 = microtime(true);
DI::profiler()->startRecording('file');
$theme_file = file_get_contents("view/theme/$theme/theme.php");
DI::profiler()->saveTimestamp($stamp1, "file");
DI::profiler()->stopRecording();
$result = preg_match("|/\*.*\*/|msU", $theme_file, $matches);

View file

@ -468,6 +468,7 @@ class Database
public function p($sql)
{
$this->profiler->startRecording('database');
$stamp1 = microtime(true);
$params = DBA::getParam(func_get_args());
@ -695,7 +696,7 @@ class Database
$this->errorno = $errorno;
}
$this->profiler->saveTimestamp($stamp1, 'database');
$this->profiler->stopRecording();
if ($this->configCache->get('system', 'db_log')) {
$stamp2 = microtime(true);
@ -727,7 +728,7 @@ class Database
public function e($sql)
{
$stamp = microtime(true);
$this->profiler->startRecording('database_write');
$params = DBA::getParam(func_get_args());
@ -779,7 +780,7 @@ class Database
$this->errorno = $errorno;
}
$this->profiler->saveTimestamp($stamp, "database_write");
$this->profiler->stopRecording();
return $retval;
}
@ -914,7 +915,7 @@ class Database
*/
public function fetch($stmt)
{
$stamp1 = microtime(true);
$this->profiler->startRecording('database');
$columns = [];
@ -962,7 +963,7 @@ class Database
}
}
$this->profiler->saveTimestamp($stamp1, 'database');
$this->profiler->stopRecording();
return $columns;
}
@ -1589,7 +1590,7 @@ class Database
public function close($stmt)
{
$stamp1 = microtime(true);
$this->profiler->startRecording('database');
if (!is_object($stmt)) {
return false;
@ -1615,7 +1616,7 @@ class Database
break;
}
$this->profiler->saveTimestamp($stamp1, 'database');
$this->profiler->stopRecording();
return $ret;
}

View file

@ -58,7 +58,7 @@ class SessionFactory
*/
public function createSession(App\Mode $mode, App\BaseURL $baseURL, IConfig $config, Database $dba, ICache $cache, LoggerInterface $logger, Profiler $profiler, array $server = [])
{
$stamp1 = microtime(true);
$profiler->startRecording('parser');
$session = null;
try {
@ -85,7 +85,7 @@ class SessionFactory
$session = new Session\Native($baseURL, $handler);
}
} finally {
$profiler->saveTimestamp($stamp1, 'parser');
$profiler->stopRecording();
return $session;
}
}

View file

@ -2858,7 +2858,7 @@ class Item
*/
private static function replaceVisualAttachments(array $attachments, string $body)
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
foreach ($attachments['visual'] as $attachment) {
if (!empty($attachment['preview'])) {
@ -2867,7 +2867,7 @@ class Item
$body = str_replace($attachment['url'], Post\Media::getUrlForId($attachment['id']), $body);
}
}
DI::profiler()->saveTimestamp($stamp1, 'rendering');
DI::profiler()->stopRecording();
return $body;
}
@ -2881,7 +2881,7 @@ class Item
*/
private static function addVisualAttachments(array $attachments, array $item, string $content, bool $shared)
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
$leading = '';
$trailing = '';
@ -2957,7 +2957,7 @@ class Item
}
}
DI::profiler()->saveTimestamp($stamp1, 'rendering');
DI::profiler()->stopRecording();
return $content;
}
@ -2973,7 +2973,7 @@ class Item
*/
private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links)
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
// @ToDo Check only for audio and video
$preview = empty($attachments['visual']);
@ -3038,7 +3038,7 @@ class Item
} elseif (preg_match("/.*(\[attachment.*?\].*?\[\/attachment\]).*/ism", $body, $match)) {
$data = BBCode::getAttachmentData($match[1]);
}
DI::profiler()->saveTimestamp($stamp1, 'rendering');
DI::profiler()->stopRecording();
if (isset($data['url']) && !in_array($data['url'], $ignore_links)) {
if (!empty($data['description']) || !empty($data['image']) || !empty($data['preview'])) {
@ -3086,7 +3086,7 @@ class Item
*/
private static function addNonVisualAttachments(array $attachments, array $item, string $content)
{
$stamp1 = microtime(true);
DI::profiler()->startRecording('rendering');
$trailing = '';
foreach ($attachments['additional'] as $attachment) {
if (strpos($item['body'], $attachment['url'])) {
@ -3112,7 +3112,7 @@ class Item
$content .= '<div class="body-attach">' . $trailing . '<div class="clear"></div></div>';
}
DI::profiler()->saveTimestamp($stamp1, 'rendering');
DI::profiler()->stopRecording();
return $content;
}

View file

@ -72,7 +72,7 @@ class HTTPRequest implements IHTTPRequest
*/
public function get(string $url, array $opts = [], &$redirects = 0)
{
$stamp1 = microtime(true);
$this->profiler->startRecording('network');
if (Network::isLocalLink($url)) {
$this->logger->info('Local link', ['url' => $url, 'callstack' => System::callstack(20)]);
@ -80,7 +80,7 @@ class HTTPRequest implements IHTTPRequest
if (strlen($url) > 1000) {
$this->logger->debug('URL is longer than 1000 characters.', ['url' => $url, 'callstack' => System::callstack(20)]);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return CurlResult::createErrorCurl(substr($url, 0, 200));
}
@ -99,14 +99,14 @@ class HTTPRequest implements IHTTPRequest
if (Network::isUrlBlocked($url)) {
$this->logger->info('Domain is blocked.', ['url' => $url]);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return CurlResult::createErrorCurl($url);
}
$ch = @curl_init($url);
if (($redirects > 8) || (!$ch)) {
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return CurlResult::createErrorCurl($url);
}
@ -208,13 +208,13 @@ class HTTPRequest implements IHTTPRequest
$redirects++;
$this->logger->notice('Curl redirect.', ['url' => $url, 'to' => $curlResponse->getRedirectUrl()]);
@curl_close($ch);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return $this->get($curlResponse->getRedirectUrl(), $opts, $redirects);
}
@curl_close($ch);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return $curlResponse;
}
@ -228,7 +228,7 @@ class HTTPRequest implements IHTTPRequest
*/
public function post(string $url, $params, array $headers = [], int $timeout = 0, &$redirects = 0)
{
$stamp1 = microtime(true);
$this->profiler->startRecording('network');
if (Network::isLocalLink($url)) {
$this->logger->info('Local link', ['url' => $url, 'callstack' => System::callstack(20)]);
@ -236,14 +236,14 @@ class HTTPRequest implements IHTTPRequest
if (Network::isUrlBlocked($url)) {
$this->logger->info('Domain is blocked.' . ['url' => $url]);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return CurlResult::createErrorCurl($url);
}
$ch = curl_init($url);
if (($redirects > 8) || (!$ch)) {
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return CurlResult::createErrorCurl($url);
}
@ -303,13 +303,13 @@ class HTTPRequest implements IHTTPRequest
$redirects++;
$this->logger->info('Post redirect.', ['url' => $url, 'to' => $curlResponse->getRedirectUrl()]);
curl_close($ch);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
return $this->post($curlResponse->getRedirectUrl(), $params, $headers, $redirects, $timeout);
}
curl_close($ch);
$this->profiler->saveTimestamp($stamp1, 'network');
$this->profiler->stopRecording();
// Very old versions of Lighttpd don't like the "Expect" header, so we remove it when needed
if ($curlResponse->getReturnCode() == 417) {
@ -358,7 +358,7 @@ class HTTPRequest implements IHTTPRequest
$url = trim($url, "'");
$stamp1 = microtime(true);
$this->profiler->startRecording('network');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -374,7 +374,7 @@ class HTTPRequest implements IHTTPRequest
$http_code = $curl_info['http_code'];
curl_close($ch);
$this->profiler->saveTimestamp($stamp1, "network");
$this->profiler->stopRecording();
if ($http_code == 0) {
return $url;
@ -403,7 +403,7 @@ class HTTPRequest implements IHTTPRequest
return $url;
}
$stamp1 = microtime(true);
$this->profiler->startRecording('network');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
@ -417,7 +417,7 @@ class HTTPRequest implements IHTTPRequest
$body = curl_exec($ch);
curl_close($ch);
$this->profiler->saveTimestamp($stamp1, "network");
$this->profiler->stopRecording();
if (trim($body) == "") {
return $url;

View file

@ -650,9 +650,9 @@ class Image
$string = $this->asString();
$stamp1 = microtime(true);
DI::profiler()->stopRecording('file');
file_put_contents($path, $string);
DI::profiler()->saveTimestamp($stamp1, "file");
DI::profiler()->stopRecording();
}
/**

View file

@ -59,9 +59,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function emergency($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->emergency($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -69,9 +69,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function alert($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->alert($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -79,9 +79,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function critical($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->critical($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -89,9 +89,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function error($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->error($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -99,9 +99,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function warning($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->warning($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -109,9 +109,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function notice($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->notice($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -119,9 +119,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function info($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->info($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -129,9 +129,9 @@ class ProfilerLogger implements LoggerInterface
*/
public function debug($message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->debug($message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
/**
@ -139,8 +139,8 @@ class ProfilerLogger implements LoggerInterface
*/
public function log($level, $message, array $context = array())
{
$stamp1 = microtime(true);
$this->profiler->startRecording('file');
$this->logger->log($level, $message, $context);
$this->profiler->saveTimestamp($stamp1, 'file');
$this->profiler->stopRecording();
}
}

View file

@ -54,6 +54,8 @@ class Profiler implements ContainerInterface
*/
private $rendertime;
private $timestamps = [];
/**
* True, if the Profiler should measure the whole rendertime including functions
*
@ -85,6 +87,48 @@ class Profiler implements ContainerInterface
$this->reset();
}
public function startRecording(string $value)
{
if (!$this->enabled) {
return;
}
$this->timestamps[] = ['value' => $value, 'stamp' => microtime(true), 'credit' => 0];
}
public function stopRecording(string $callstack = '')
{
if (!$this->enabled || empty($this->timestamps)) {
return;
}
$timestamp = array_pop($this->timestamps);
$duration = floatval(microtime(true) - $timestamp['stamp'] - $timestamp['credit']);
$value = $timestamp['value'];
foreach ($this->timestamps as $key => $stamp) {
$this->timestamps[$key]['credit'] += $duration;
}
$callstack = $callstack ?: System::callstack(4, $value == 'rendering' ? 0 : 1);
if (!isset($this->performance[$value])) {
// Prevent ugly E_NOTICE
$this->performance[$value] = 0;
}
$this->performance[$value] += (float) $duration;
$this->performance['marktime'] += (float) $duration;
if (!isset($this->callstack[$value][$callstack])) {
// Prevent ugly E_NOTICE
$this->callstack[$value][$callstack] = 0;
}
$this->callstack[$value][$callstack] += (float) $duration;
}
/**
* Saves a timestamp for a value - f.e. a call
* Necessary for profiling Friendica
@ -227,6 +271,15 @@ class Profiler implements ContainerInterface
}
}
}
if (isset($this->callstack["rendering"])) {
$output .= "\nRendering:\n";
foreach ($this->callstack["rendering"] as $func => $time) {
$time = round($time, 3);
if ($time > $limit) {
$output .= $func . ": " . $time . "\n";
}
}
}
return $output;
}

View file

@ -250,11 +250,12 @@ class ProfilerTest extends MockedTest
->once();
$profiler = new Profiler($configCache);
$profiler->startRecording('network');
self::assertFalse($profiler->isRendertime());
self::assertEmpty($profiler->getRendertimeString());
$profiler->saveTimestamp(time(), 'network', 'test1');
$profiler->stopRecording('test1');
$config = \Mockery::mock(IConfig::class);
$config->shouldReceive('get')
@ -282,7 +283,8 @@ class ProfilerTest extends MockedTest
$profiler->update($config);
$profiler->saveTimestamp(time(), 'database', 'test2');
$profiler->startRecording('database');
$profiler->stopRecording('test2');
self::assertTrue($profiler->isRendertime());
$output = $profiler->getRendertimeString();

File diff suppressed because it is too large Load diff