SpringBootMonitor
spring-boot-admin源码分析及单机监控spring-boot-monitor的实现(一)
spring-boot-admin源码分析及单机监控spring-boot-monitor的实现(二)
spring-boot-admin源码分析及单机监控spring-boot-monitor的实现(三)
1.spring-boot-monitor设计
设计我们自己的springbootmonitor,就不能用springbootadmin的那套东西,需要自己画页面。
新建登陆页面login.html。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>sbim monitor</title> <link href='css/bootstrap.min.css' rel="stylesheet" > <script type="text/javascript" src="js/jquery.min.js"></script> <style type="text/css"> /* Override some defaults */ html, body { background-color: #eee; } body { padding-top: 40px; } .container { width: 300px; } /* The white background content wrapper */ .container > .content { background-color: #fff; padding: 20px; margin: 0 -20px; -webkit-border-radius: 10px 10px 10px 10px; -moz-border-radius: 10px 10px 10px 10px; border-radius: 10px 10px 10px 10px; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15); -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15); box-shadow: 0 1px 2px rgba(0,0,0,.15); } .login-form { margin-left: 65px; } legend { margin-right: -50px; font-weight: bold; color: #404040; } </style> </head> <body> <div class="container"> <div class="content"> <div class="row"> <div class="login-form"> <h2>Login</h2> <form id="loginForm" method="post" autocomplete="off" > <fieldset> <div id="alertInfo" class="alert alert-error clearfix" style="margin-bottom: 5px;width: 195px; padding: 2px 15px 2px 10px;display: none;"> The username or password you entered is incorrect. </div> <div class="clearfix"> <input type="text" placeholder="用户名" name="loginUsername" > </div> <div class="clearfix"> <input type="password" placeholder="密码" name="loginPassword"> </div> <button id="loginBtn" class="btn btn-primary" type="button">Sign in</button> <button class="btn" type="reset">Reset</button> </fieldset> </form> </div> </div> </div> </div> <!-- /container --> <script type="text/javascript"> $.namespace("sbim.login"); sbim.login = function () { return { login : function() { $.ajax({ type: 'POST', url: "api/login", data: $("#loginForm").serialize(), success: function(data) { if("success" == data) location.href = "index.html"; else { $("#alertInfo").show(); $("#loginForm")[0].reset(); } }, dataType: "text" }); } } }(); $(document).ready(function() { $("#loginBtn").click(sbim.login.login); }); </script> </body> </html>
使用jquery与后台进行交互。
2.spring-boot-monitor后台设计
package com.cff.boot.monitor.web;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cff.boot.monitor.config.MonitorProperties;
import com.cff.boot.monitor.model.AppInfo;
import com.cff.boot.monitor.model.SbimUser;
import com.cff.boot.monitor.store.SimpleAppInfoStore;
@WebController
@RequestMapping("/sbim/api")
@ResponseBody
public class RestApiController {
private final MonitorProperties monitorProperties;
private final SimpleAppInfoStore simpleAppInfoStore;
private String contextPath = "/";
public RestApiController(MonitorProperties monitorProperties, SimpleAppInfoStore simpleAppInfoStore) {
this.monitorProperties = monitorProperties;
this.simpleAppInfoStore = simpleAppInfoStore;
contextPath = monitorProperties.getContextPath();
}
@RequestMapping(value= "/login", method=RequestMethod.POST)
public String login(@RequestParam String loginUsername, @RequestParam String loginPassword, HttpServletRequest req) {
SbimUser sbimUser = new SbimUser();
sbimUser.setLoginUsername(loginUsername);
sbimUser.setLoginPassword(loginPassword);
if (monitorProperties.getUsername().equals(sbimUser.getLoginUsername())
&& monitorProperties.getPassword().equals(sbimUser.getLoginPassword())){
req.getSession().setAttribute("sbimUser", sbimUser);
return "success";
} else {
return "failed";
}
}
@RequestMapping(value= "/appInfo", method=RequestMethod.POST)
public List<AppInfo> appInfo(HttpServletRequest req) {
SbimUser sbimUser = (SbimUser) req.getSession().getAttribute("sbimUser");
if(sbimUser == null){
return null;
}
List<AppInfo> lists = simpleAppInfoStore.getAll();
return lists;
}
@RequestMapping(value= "/appRemove", method=RequestMethod.POST)
public List<AppInfo> appRemove(HttpServletRequest req) {
SbimUser sbimUser = (SbimUser) req.getSession().getAttribute("sbimUser");
if(sbimUser == null){
return null;
}
String appName = req.getParameter("appName");
simpleAppInfoStore.remove(appName);
List<AppInfo> lists = simpleAppInfoStore.getAll();
return lists;
}
}
后台提供登陆接口,可以将登陆信息直接放入session,这样做的目的是可以不用使用springsecurity控制登陆。自己实现简单的登陆。
3.SimpleAppInfoStore应用信息存储
虽然是单机监控,我们还是要存储应用信息,方便与前台进行交互。
package com.cff.boot.monitor.store; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.cff.boot.monitor.model.AppInfo; public class SimpleAppInfoStore { private final ConcurrentMap<String, AppInfo> map = new ConcurrentHashMap<>(); public SimpleAppInfoStore() { } public void addApp(AppInfo appInfo){ map.put(appInfo.getAppId(), appInfo); } public void remove(String appId){ map.remove(appId); } public List<AppInfo> getAll(){ List<AppInfo> lists = new ArrayList<AppInfo>(map.values()); return lists; } public AppInfo getApp(String appId){ return map.get(appId); } }
类似于springbootadmin,我们都使用ConcurrentMap去存储应用信息,虽然并不必要。
这样,一个简单的监控登陆+首页已经ok了。剩下的就是不断添加前台页面和后台逻辑的问题了。