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
133
134
135
136
137
138
139
140
141
142
143
|
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use Time::HiRes qw(gettimeofday tv_interval);
use BSD::Resource; # For memory and granular CPU usage
# 1. Start Benchmark Timer
my $start_time = [gettimeofday];
sub escape_html {
my $str = shift;
return "" unless defined $str;
$str =~ s/&/&/g;
$str =~ s/</</g;
$str =~ s/>/>/g;
$str =~ s/"/"/g;
$str =~ s/'/'/g;
return $str;
}
my %params;
if ($ENV{QUERY_STRING}) {
foreach my $pair (split /&/, $ENV{QUERY_STRING}) {
my ($key, $value) = split /=/, $pair;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$params{$key} = $value;
}
}
my $search_text = $params{'q'} || '';
$search_text = substr($search_text, 0, 64);
$search_text =~ s/[^a-zA-Z0-9 ]//g;
my $directory = '../log/';
my @results;
my %excluded_files = (
'index.html' => 1,
);
# Track IO operations (simple count)
my $files_read = 0;
if ($search_text =~ /\S/) {
find({
wanted => sub {
return unless -f $_ && $_ eq 'index.html';
my $rel_path = $File::Find::name;
$rel_path =~ s|^\Q$directory\E/?||;
return if $excluded_files{$rel_path};
if (open my $fh, '<', $_) {
$files_read++; # Tracking IO
my $content = do { local $/; <$fh> };
close $fh;
if ($content =~ /\Q$search_text\E/i) {
my ($title) = $content =~ /<title>(.*?)<\/title>/is;
$title = $title ? escape_html($title) : $rel_path;
my ($p_content) = $content =~ /<p[^>]*>(.*?)<\/p>/is;
my $snippet = $p_content || "";
$snippet =~ s/<[^>]*>//g;
$snippet =~ s/\s+/ /g;
$snippet = escape_html(substr($snippet, 0, 50));
$snippet .= "..." if length($p_content || "") > 50;
push @results, {
path => $File::Find::name,
title => $title,
snippet => $snippet
};
}
}
},
no_chdir => 0,
follow => 0,
}, $directory);
}
# --- 2. Calculate Metrics ---
my $end_time = [gettimeofday];
my $elapsed = tv_interval($start_time, $end_time);
# CPU & RAM Usage via BSD::Resource
my $rusage = getrusage();
my $user_cpu = $rusage->utime; # User CPU time
my $system_cpu = $rusage->stime; # System CPU time
my $max_rss = $rusage->maxrss; # Peak RAM (usually in KB on Linux)
# --- 3. Output ---
print "Content-Type: text/html\n\n";
my $list;
if ($search_text eq '') {
$list = "<p>Please enter a search term above.</p>";
} elsif (@results == 0) {
$list = "<p>No results found for \"<b>$search_text</b>\".</p>";
} else {
$list = "<ul>";
foreach my $res (@results) {
my $url = $res->{path};
$list .= "<li><a href=\"/$url\">$res->{title}</a><br><small>$res->{snippet}</small></li>";
}
$list .= "</ul>";
}
my $safe_search_text = escape_html($search_text);
print <<"HTML";
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Search Results</title>
<style>
.stats { background: #f4f4f4; padding: 10px; border-radius: 5px; font-family: monospace; font-size: 0.85em; margin-top: 20px; border: 1px solid #ddd; }
</style>
</head>
<body>
<div class="container">
<h2>Search</h2>
<form action="" method="GET">
<input type="text" name="q" value="$safe_search_text">
<input type="submit" value="Search">
</form>
$list
<div class="stats">
<strong>Performance Metrics:</strong><br>
Total Time: @{[ sprintf("%.4f", $elapsed) ]} seconds<br>
User CPU: $user_cpu s<br>
System CPU: $system_cpu s<br>
Peak RAM: $max_rss KB<br>
Files Read: $files_read (IO Activity)
</div>
</div>
</body>
</html>
HTML
|