Skip to content

Commit e07ebb1

Browse files
committed
refactor profiler to support http with html crawling in additional to local filesystem #798
1 parent b2d6bed commit e07ebb1

36 files changed

+1542
-899
lines changed

META-INF/plugin.xml

+7
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@
285285
nonDefaultProject="true"
286286
/>
287287

288+
<projectConfigurable instance="fr.adrienbrault.idea.symfony2plugin.profiler.ui.ProfilerSettingsDialog"
289+
displayName="Profiler"
290+
parentId="Symfony2.SettingsForm"
291+
id="Symfony.ProfilerSettingsForm"
292+
nonDefaultProject="true"
293+
/>
294+
288295
<php.typeProvider2 implementation="fr.adrienbrault.idea.symfony2plugin.dic.SymfonyContainerTypeProvider"/>
289296
<php.typeProvider2 implementation="fr.adrienbrault.idea.symfony2plugin.doctrine.ObjectRepositoryTypeProvider"/>
290297
<php.typeProvider2 implementation="fr.adrienbrault.idea.symfony2plugin.doctrine.ObjectRepositoryResultTypeProvider"/>

src/fr/adrienbrault/idea/symfony2plugin/Settings.java

+6
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ public class Settings implements PersistentStateComponent<Settings> {
8888

8989
public boolean dismissEnableNotification = false;
9090

91+
public boolean profilerLocalEnabled = false;
92+
public String profilerLocalUrl = "http://127.0.0.1:8000";
93+
94+
public boolean profilerHttpEnabled = false;
95+
public String profilerHttpUrl = "http://127.0.0.1:8000";
96+
9197
@Nullable
9298
public List<TwigNamespaceSetting> twigNamespaces = new ArrayList<>();
9399

src/fr/adrienbrault/idea/symfony2plugin/Symfony2ProjectComponent.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
1919
import fr.adrienbrault.idea.symfony2plugin.util.IdeHelper;
2020
import fr.adrienbrault.idea.symfony2plugin.util.service.ServiceXmlParserFactory;
21-
import fr.adrienbrault.idea.symfony2plugin.widget.SymfonyProfilerWidget;
21+
import fr.adrienbrault.idea.symfony2plugin.profiler.widget.SymfonyProfilerWidget;
2222
import org.jetbrains.annotations.NotNull;
2323
import org.jetbrains.annotations.Nullable;
2424

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package fr.adrienbrault.idea.symfony2plugin.profiler;
2+
3+
import com.intellij.openapi.project.Project;
4+
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.ProfilerRequestInterface;
5+
import fr.adrienbrault.idea.symfony2plugin.profiler.utils.ProfilerUtil;
6+
import org.apache.commons.lang.StringUtils;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.List;
12+
13+
/**
14+
* @author Daniel Espendiller <daniel@espendiller.net>
15+
*/
16+
public class HttpProfilerIndex implements ProfilerIndexInterface {
17+
/**
18+
* http://127.0.0.1:8080/_profiler
19+
*/
20+
private static String PROFILER_PATH = "_profiler";
21+
22+
@NotNull
23+
private final Project project;
24+
25+
@NotNull
26+
private final String url;
27+
28+
public HttpProfilerIndex(@NotNull Project project, @NotNull String url) {
29+
this.project = project;
30+
this.url = StringUtils.stripEnd(url, "/");
31+
}
32+
33+
@NotNull
34+
@Override
35+
public List<ProfilerRequestInterface> getRequests() {
36+
String content = ProfilerUtil.getProfilerUrlContent(String.format("%s/%s/empty/search/results?ip=&limit=10", this.url, PROFILER_PATH));
37+
if(content == null) {
38+
return Collections.emptyList();
39+
}
40+
41+
return new ArrayList<>(ProfilerUtil.collectHttpDataForRequest(
42+
project, ProfilerUtil.createRequestsFromIndexHtml(this.project, content, this.url))
43+
);
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package fr.adrienbrault.idea.symfony2plugin.profiler;
2+
3+
import com.intellij.util.containers.ContainerUtil;
4+
import fr.adrienbrault.idea.symfony2plugin.profiler.collector.LocalDefaultDataCollector;
5+
import fr.adrienbrault.idea.symfony2plugin.profiler.collector.LocalMailCollector;
6+
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.LocalProfilerRequest;
7+
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.ProfilerRequestInterface;
8+
import fr.adrienbrault.idea.symfony2plugin.profiler.reader.ReverseFileLineReader;
9+
import fr.adrienbrault.idea.symfony2plugin.profiler.utils.ProfilerUtil;
10+
import org.apache.commons.lang.StringUtils;
11+
import org.jetbrains.annotations.NotNull;
12+
import org.jetbrains.annotations.Nullable;
13+
14+
import java.io.BufferedReader;
15+
import java.io.File;
16+
import java.io.FileReader;
17+
import java.io.IOException;
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.List;
21+
import java.util.concurrent.Callable;
22+
23+
/**
24+
* @author Daniel Espendiller <daniel@espendiller.net>
25+
*/
26+
public class LocalProfilerIndex implements ProfilerIndexInterface {
27+
@NotNull
28+
private File file;
29+
30+
public LocalProfilerIndex(@NotNull File file) {
31+
this.file = file;
32+
}
33+
34+
@NotNull
35+
public List<ProfilerRequestInterface> getRequests() {
36+
List<String> lines = new ArrayList<>();
37+
38+
try {
39+
// empty line and end of line need +1
40+
ContainerUtil.addAll(lines, new ReverseFileLineReader(this.file, "UTF-8", 11).readLines());
41+
} catch (IOException ignored) {
42+
}
43+
44+
Collection<Callable<ProfilerRequestInterface>> callable = new ArrayList<>();
45+
46+
// build thread callable collection
47+
lines.stream().filter(StringUtils::isNotBlank).forEachOrdered(line -> {
48+
String[] split = line.split(",");
49+
if (split.length < 6) {
50+
return;
51+
}
52+
53+
callable.add(new MyProfilerRequestBuilderCallable(split));
54+
});
55+
56+
return ProfilerUtil.getProfilerRequestCollectorDecorated(callable, 15);
57+
}
58+
59+
@NotNull
60+
private String getPath(@NotNull String hash) {
61+
String[] hashSplit = hash.split("(?<=\\G.{2})");
62+
return hashSplit[2] + "/" + hashSplit[1] + "/" + hash;
63+
}
64+
65+
@Nullable
66+
private File getFile(@NotNull String hash) {
67+
String path = this.getPath(hash);
68+
69+
File file = new File(this.file.getParentFile().getAbsolutePath() + "/" + path);
70+
if(!file.exists()) {
71+
return null;
72+
}
73+
74+
return file;
75+
}
76+
77+
@Nullable
78+
private String getContentForHash(@NotNull String hash) {
79+
File file = this.getFile(hash);
80+
if(file == null) {
81+
return null;
82+
}
83+
84+
StringBuilder content = new StringBuilder();
85+
86+
try {
87+
BufferedReader in = new BufferedReader(new FileReader(file));
88+
String str;
89+
while ((str = in.readLine()) != null) {
90+
content.append(str);
91+
}
92+
in.close();
93+
} catch (IOException ignored) {
94+
}
95+
96+
return content.toString();
97+
}
98+
99+
private class MyProfilerRequestBuilderCallable implements Callable<ProfilerRequestInterface> {
100+
private final String[] split;
101+
102+
MyProfilerRequestBuilderCallable(String[] split) {
103+
this.split = split;
104+
}
105+
106+
@Override
107+
public ProfilerRequestInterface call() throws Exception {
108+
String content = getContentForHash(split[0]);
109+
if(content == null) {
110+
return new LocalProfilerRequest(split);
111+
}
112+
113+
return new LocalProfilerRequest(
114+
split,
115+
new LocalDefaultDataCollector(content),
116+
new LocalMailCollector(content)
117+
);
118+
}
119+
}
120+
}

src/fr/adrienbrault/idea/symfony2plugin/profiler/ProfilerIndex.java

-95
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package fr.adrienbrault.idea.symfony2plugin.profiler;
2+
3+
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.ProfilerRequestInterface;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.List;
7+
8+
/**
9+
* @author Daniel Espendiller <daniel@espendiller.net>
10+
*/
11+
public interface ProfilerIndexInterface {
12+
@NotNull
13+
List<ProfilerRequestInterface> getRequests();
14+
}

0 commit comments

Comments
 (0)