
Diagnostic: Introduce the Diagnostic
Site Administrator can see the list of problems of Yobi in Site Management > Diagnostics. I believe this way is much better than finding an error log among the tons of log entries. When a site administrator tries to see the list, the Diagnostic runs every diagnostic item added by Yobi developers. The developers can add their own diagnostic item by using Diagnostic.register method.
@cca0ece843bdf3b405dad21739aec48cb8c26df6
--- app/Global.java
+++ app/Global.java
... | ... | @@ -46,10 +46,21 @@ |
46 | 46 |
import play.mvc.Result; |
47 | 47 |
import play.libs.F.Promise; |
48 | 48 |
|
49 |
-import utils.AccessControl; |
|
50 |
-import utils.AccessLogger; |
|
51 |
-import utils.ErrorViews; |
|
52 |
-import utils.YamlUtil; |
|
49 |
+import play.mvc.Result; |
|
50 |
+import play.mvc.Results; |
|
51 |
+import utils.*; |
|
52 |
+import views.html.welcome.restart; |
|
53 |
+import views.html.welcome.secret; |
|
54 |
+ |
|
55 |
+import java.io.IOException; |
|
56 |
+import java.lang.reflect.Method; |
|
57 |
+import java.math.BigInteger; |
|
58 |
+import java.net.InetAddress; |
|
59 |
+import java.nio.file.Files; |
|
60 |
+import java.nio.file.Path; |
|
61 |
+import java.nio.file.Paths; |
|
62 |
+import java.security.SecureRandom; |
|
63 |
+import java.util.Date; |
|
53 | 64 |
|
54 | 65 |
import views.html.welcome.secret; |
55 | 66 |
import views.html.welcome.restart; |
... | ... | @@ -69,6 +80,7 @@ |
69 | 80 |
isSecretInvalid = equalsDefaultSecret(); |
70 | 81 |
insertInitialData(); |
71 | 82 |
|
83 |
+ Config.onStart(); |
|
72 | 84 |
PullRequest.onStart(); |
73 | 85 |
NotificationMail.onStart(); |
74 | 86 |
NotificationEvent.onStart(); |
--- app/controllers/SiteApp.java
+++ app/controllers/SiteApp.java
... | ... | @@ -268,4 +268,12 @@ |
268 | 268 |
return ok(update.render("title.siteSetting", currentVersion, |
269 | 269 |
YobiUpdate.versionToUpdate, exception)); |
270 | 270 |
} |
271 |
+ |
|
272 |
+ /** |
|
273 |
+ * Diagnose Yobi |
|
274 |
+ * @return |
|
275 |
+ */ |
|
276 |
+ public static Result diagnose() { |
|
277 |
+ return ok(diagnostic.render("title.siteSetting", Diagnostic.checkAll())); |
|
278 |
+ } |
|
271 | 279 |
} |
--- app/utils/Config.java
+++ app/utils/Config.java
... | ... | @@ -34,6 +34,23 @@ |
34 | 34 |
public class Config { |
35 | 35 |
public static final String DEFAULT_SCHEME = "http"; |
36 | 36 |
|
37 |
+ public static void onStart() { |
|
38 |
+ Diagnostic.register(new SimpleDiagnostic() { |
|
39 |
+ @Override |
|
40 |
+ public String checkOne() { |
|
41 |
+ Configuration config = Configuration.root(); |
|
42 |
+ |
|
43 |
+ if (config.getInt("application.port") != null |
|
44 |
+ && config.getInt("application.hostname") == null) { |
|
45 |
+ return "application.port may be ignored because " + |
|
46 |
+ "application.hostname is not configured."; |
|
47 |
+ } else { |
|
48 |
+ return null; |
|
49 |
+ } |
|
50 |
+ } |
|
51 |
+ }); |
|
52 |
+ } |
|
53 |
+ |
|
37 | 54 |
public static String getSiteName() { |
38 | 55 |
return ObjectUtils.defaultIfNull( |
39 | 56 |
play.Configuration.root().getString("application.siteName"), "Yobi"); |
... | ... | @@ -57,10 +74,6 @@ |
57 | 74 |
return hostname; |
58 | 75 |
} |
59 | 76 |
} else { |
60 |
- if (play.Configuration.root().getInt("application.port") != null) { |
|
61 |
- play.Logger.warn("application.port is ignored because application.hostname is not" + |
|
62 |
- " configured."); |
|
63 |
- } |
|
64 | 77 |
return defaultValue; |
65 | 78 |
} |
66 | 79 |
} |
+++ app/utils/Diagnostic.java
... | ... | @@ -0,0 +1,64 @@ |
1 | +/** | |
2 | + * Yobi, Project Hosting SW | |
3 | + * | |
4 | + * Copyright 2014 NAVER Corp. | |
5 | + * http://yobi.io | |
6 | + * | |
7 | + * @Author Yi EungJun | |
8 | + * | |
9 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
10 | + * you may not use this file except in compliance with the License. | |
11 | + * You may obtain a copy of the License at | |
12 | + * | |
13 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
14 | + * | |
15 | + * Unless required by applicable law or agreed to in writing, software | |
16 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
17 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
18 | + * See the License for the specific language governing permissions and | |
19 | + * limitations under the License. | |
20 | + */ | |
21 | +package utils; | |
22 | + | |
23 | +import org.apache.commons.lang3.exception.ExceptionUtils; | |
24 | + | |
25 | +import javax.annotation.Nonnull; | |
26 | +import java.util.ArrayList; | |
27 | +import java.util.List; | |
28 | +import java.util.concurrent.CopyOnWriteArrayList; | |
29 | + | |
30 | +abstract public class Diagnostic { | |
31 | + | |
32 | + private final static List<Diagnostic> diagnostics = new CopyOnWriteArrayList<>(); | |
33 | + | |
34 | + /** | |
35 | + * Register a diagnostic. | |
36 | + * | |
37 | + * Registered diagnostics are run when someone open Site Management > | |
38 | + * Diagnostics page. | |
39 | + * | |
40 | + * @param diagnostic | |
41 | + */ | |
42 | + public static void register(@Nonnull Diagnostic diagnostic) { | |
43 | + diagnostics.add(diagnostic); | |
44 | + } | |
45 | + | |
46 | + @Nonnull | |
47 | + public static List<String> checkAll() { | |
48 | + List<String> errors = new ArrayList<>(); | |
49 | + | |
50 | + for (Diagnostic diagnostic : diagnostics) { | |
51 | + try { | |
52 | + errors.addAll(diagnostic.check()); | |
53 | + } catch (Exception e) { | |
54 | + errors.add("Failed to diagnose: " | |
55 | + + ExceptionUtils.getStackTrace(e)); | |
56 | + } | |
57 | + } | |
58 | + | |
59 | + return errors; | |
60 | + } | |
61 | + | |
62 | + @Nonnull | |
63 | + abstract public List<String> check(); | |
64 | +} |
+++ app/utils/SimpleDiagnostic.java
... | ... | @@ -0,0 +1,43 @@ |
1 | +/** | |
2 | + * Yobi, Project Hosting SW | |
3 | + * | |
4 | + * Copyright 2014 NAVER Corp. | |
5 | + * http://yobi.io | |
6 | + * | |
7 | + * @Author Yi EungJun | |
8 | + * | |
9 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
10 | + * you may not use this file except in compliance with the License. | |
11 | + * You may obtain a copy of the License at | |
12 | + * | |
13 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
14 | + * | |
15 | + * Unless required by applicable law or agreed to in writing, software | |
16 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
17 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
18 | + * See the License for the specific language governing permissions and | |
19 | + * limitations under the License. | |
20 | + */ | |
21 | +package utils; | |
22 | + | |
23 | +import javax.annotation.Nonnull; | |
24 | +import java.util.ArrayList; | |
25 | +import java.util.List; | |
26 | + | |
27 | +abstract public class SimpleDiagnostic extends Diagnostic { | |
28 | + @Override | |
29 | + @Nonnull | |
30 | + public List<String> check() { | |
31 | + List<String> errors = new ArrayList<>(); | |
32 | + | |
33 | + String error = checkOne(); | |
34 | + | |
35 | + if (error != null) { | |
36 | + errors.add(error); | |
37 | + } | |
38 | + | |
39 | + return errors; | |
40 | + } | |
41 | + | |
42 | + abstract public String checkOne(); | |
43 | +} |
+++ app/views/site/diagnostic.scala.html
... | ... | @@ -0,0 +1,41 @@ |
1 | +@** | |
2 | +* Yobi, Project Hosting SW | |
3 | +* | |
4 | +* Copyright 2014 NAVER Corp. | |
5 | +* http://yobi.io | |
6 | +* | |
7 | +* @Author Yi EungJun | |
8 | +* | |
9 | +* Licensed under the Apache License, Version 2.0 (the "License"); | |
10 | +* you may not use this file except in compliance with the License. | |
11 | +* You may obtain a copy of the License at | |
12 | +* | |
13 | +* http://www.apache.org/licenses/LICENSE-2.0 | |
14 | +* | |
15 | +* Unless required by applicable law or agreed to in writing, software | |
16 | +* distributed under the License is distributed on an "AS IS" BASIS, | |
17 | +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
18 | +* See the License for the specific language governing permissions and | |
19 | +* limitations under the License. | |
20 | +**@ | |
21 | +@(message: String, errors: List[String]) | |
22 | + | |
23 | +@import org.apache.commons.lang.exception.ExceptionUtils | |
24 | +@import utils.TemplateHelper._ | |
25 | + | |
26 | +@siteMngLayout(message) { | |
27 | + <div class="title_area"> | |
28 | + <h2 class="pull-left">@Messages("site.sidebar.diagnostics")</h2> | |
29 | + </div> | |
30 | + | |
31 | + @if(errors.isEmpty()) { | |
32 | + <p>@Messages("site.diagnostic.errorNotFound")</p> | |
33 | + } else { | |
34 | + <p>@Messages("site.diagnostic.errorFound", errors.size())</p> | |
35 | + <ul> | |
36 | + @for(error <- errors) { | |
37 | + <li><pre>@error</pre></li> | |
38 | + } | |
39 | + </ul> | |
40 | + } | |
41 | +} |
--- app/views/site/siteMngLayout.scala.html
+++ app/views/site/siteMngLayout.scala.html
... | ... | @@ -64,6 +64,9 @@ |
64 | 64 |
@if(YobiUpdate.versionToUpdate != null) { <span class="notification-badge">1</span> } |
65 | 65 |
</a> |
66 | 66 |
</li> |
67 |
+ <li class="@isActiveMenu(routes.SiteApp.diagnose())"> |
|
68 |
+ <a href="@routes.SiteApp.diagnose()">@Messages("site.sidebar.diagnostics")</a> |
|
69 |
+ </li> |
|
67 | 70 |
</ul> |
68 | 71 |
</div> |
69 | 72 |
<div class="span10"> |
--- conf/messages
+++ conf/messages
... | ... | @@ -728,6 +728,8 @@ |
728 | 728 |
search.scope.group = This Group |
729 | 729 |
search.scope.porject = This Project |
730 | 730 |
site = Site |
731 |
+site.diagnostic.errorFound = {0} errors were found |
|
732 |
+site.diagnostic.errorNotFound = No errors were found |
|
731 | 733 |
site.features.codeManagement = Your code is safely stored in a version controlled system. |
732 | 734 |
site.features.codeReview = Review all changes in code with your team before merging. Code discussion will help you improve your code. |
733 | 735 |
site.features.issueTracker = Yobi provides an issue tracker to help you deal with your issues more easily and clearly. |
... | ... | @@ -763,6 +765,7 @@ |
763 | 765 |
site.sidebar.projectList = Projects |
764 | 766 |
site.sidebar.userList = Users |
765 | 767 |
site.sidebar.update = Software Update |
768 |
+site.sidebar.diagnostics = Diagnostics |
|
766 | 769 |
site.update.currentVersion = Current version is Yobi {0} |
767 | 770 |
site.update.download = Download |
768 | 771 |
site.update.isAvailable = Yobi {0} is available |
--- conf/messages.ko
+++ conf/messages.ko
... | ... | @@ -729,6 +729,8 @@ |
729 | 729 |
search.scope.group = 현재 그룹 |
730 | 730 |
search.scope.porject = 현재 프로젝트 |
731 | 731 |
site = 사이트 |
732 |
+site.diagnostic.errorFound = {0}개의 문제점이 발견되었습니다. |
|
733 |
+site.diagnostic.errorNotFound = 아무런 문제가 발견되지 않았습니다. |
|
732 | 734 |
site.features.codeManagement = 작성한 코드는 모두 이력이 관리되는 형태로 안전하게 서버에 보관됩니다. |
733 | 735 |
site.features.codeReview = 변경된 코드를 보면서 팀원들과 토론해보세요. 코드의 완성도를 더욱 높일 수 있습니다. |
734 | 736 |
site.features.issueTracker = 팀이 함께 고민하고 처리해야 하는 내용들을 적고 거친 파도를 합심해 헤쳐나가듯 해결해 나갑니다. |
... | ... | @@ -764,6 +766,7 @@ |
764 | 766 |
site.sidebar.projectList = 프로젝트 |
765 | 767 |
site.sidebar.userList = 사용자 |
766 | 768 |
site.sidebar.update = 업데이트 |
769 |
+site.sidebar.diagnostics = 시스템 진단 |
|
767 | 770 |
site.update.currentVersion = 현재 버전은 {0} 입니다 |
768 | 771 |
site.update.download = 다운로드 |
769 | 772 |
site.update.error = 다음과 같이 에러가 발생하여 업데이트 할 버전을 확인하지 못했습니다. |
--- conf/routes
+++ conf/routes
... | ... | @@ -80,6 +80,7 @@ |
80 | 80 |
POST /sites/toggleAccountLock controllers.SiteApp.toggleAccountLock(loginId: String, state: String ?= null, query: String ?= null) |
81 | 81 |
GET /sites/update controllers.SiteApp.update() |
82 | 82 |
POST /sites/unwatchUpdate controllers.SiteApp.unwatchUpdate() |
83 |
+GET /sites/diagnostic controllers.SiteApp.diagnose() |
|
83 | 84 |
GET /lostPassword controllers.PasswordResetApp.lostPassword |
84 | 85 |
POST /lostPassword controllers.PasswordResetApp.requestResetPasswordEmail() |
85 | 86 |
GET /resetPassword controllers.PasswordResetApp.resetPasswordForm(s:String) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?