Переглянути джерело

增加阿里云SLS日志查看服务

luoshi 5 роки тому
коміт
ae86a10ad7

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+target
+.idea
+*.iml

+ 74 - 0
pom.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.qmth.ops</groupId>
+    <artifactId>aliyun-ops</artifactId>
+    <version>1.0.0</version>
+    <name>aliyun-ops</name>
+    <description>aliyun ops service</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.7.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-ram</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-sts</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.5.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.68</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 16 - 0
src/main/java/com/qmth/ops/aliyun/AliyunOpsApplication.java

@@ -0,0 +1,16 @@
+package com.qmth.ops.aliyun;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * Aliyun ops application
+ */
+@SpringBootApplication
+public class AliyunOpsApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AliyunOpsApplication.class, args);
+    }
+
+}

+ 89 - 0
src/main/java/com/qmth/ops/aliyun/config/SlsConfig.java

@@ -0,0 +1,89 @@
+package com.qmth.ops.aliyun.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "sls")
+public class SlsConfig {
+
+    private String ramName;
+
+    private String ramAssumeRole;
+
+    private String accessKey;
+
+    private String accessSecret;
+
+    private String redirectUrl;
+
+    private String queryUrl;
+
+    private String tokenUrl;
+
+    private String signUrl;
+
+    public String getRamName() {
+        return ramName;
+    }
+
+    public void setRamName(String ramName) {
+        this.ramName = ramName;
+    }
+
+    public String getRamAssumeRole() {
+        return ramAssumeRole;
+    }
+
+    public void setRamAssumeRole(String ramAssumeRole) {
+        this.ramAssumeRole = ramAssumeRole;
+    }
+
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    public String getAccessSecret() {
+        return accessSecret;
+    }
+
+    public void setAccessSecret(String accessSecret) {
+        this.accessSecret = accessSecret;
+    }
+
+    public String getRedirectUrl() {
+        return redirectUrl;
+    }
+
+    public void setRedirectUrl(String redirectUrl) {
+        this.redirectUrl = redirectUrl;
+    }
+
+    public String getQueryUrl() {
+        return queryUrl;
+    }
+
+    public void setQueryUrl(String queryUrl) {
+        this.queryUrl = queryUrl;
+    }
+
+    public String getTokenUrl() {
+        return tokenUrl;
+    }
+
+    public void setTokenUrl(String tokenUrl) {
+        this.tokenUrl = tokenUrl;
+    }
+
+    public String getSignUrl() {
+        return signUrl;
+    }
+
+    public void setSignUrl(String signUrl) {
+        this.signUrl = signUrl;
+    }
+}

+ 19 - 0
src/main/java/com/qmth/ops/aliyun/controller/IndexController.java

@@ -0,0 +1,19 @@
+package com.qmth.ops.aliyun.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author luoshi
+ * @date 2019/3/2309:54
+ */
+@RestController
+public class IndexController {
+
+    @RequestMapping("/")
+    public Mono<String> index() {
+        return Mono.just("ok");
+    }
+
+}

+ 32 - 0
src/main/java/com/qmth/ops/aliyun/controller/SlsController.java

@@ -0,0 +1,32 @@
+package com.qmth.ops.aliyun.controller;
+
+import com.qmth.ops.aliyun.utils.SlsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author luoshi
+ * @date 2019/3/23 09:54
+ */
+@RestController
+@RequestMapping("/sls")
+@CrossOrigin
+public class SlsController {
+
+    @Autowired
+    private SlsService slsService;
+
+    @RequestMapping("/project")
+    public Mono<Object> list() {
+        return Mono.just(slsService.getProject());
+    }
+
+    @RequestMapping("/view")
+    public Mono<String> view(@RequestParam String project, @RequestParam String store) {
+        return slsService.view(project, store);
+    }
+}

+ 28 - 0
src/main/java/com/qmth/ops/aliyun/utils/AssumeRoleClient.java

@@ -0,0 +1,28 @@
+package com.qmth.ops.aliyun.utils;
+
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
+import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
+import com.qmth.ops.aliyun.config.SlsConfig;
+
+public class AssumeRoleClient {
+
+    private static final String REGION_ID = "cn-hangzhou";
+
+    public static AssumeRoleResponse get(SlsConfig config) {
+        DefaultProfile profile = DefaultProfile.getProfile(REGION_ID, config.getAccessKey(), config.getAccessSecret());
+        IAcsClient client = new DefaultAcsClient(profile);
+
+        AssumeRoleRequest request = new AssumeRoleRequest();
+        request.setRegionId(REGION_ID);
+        request.setRoleArn(config.getRamAssumeRole());
+        request.setRoleSessionName(config.getRamName());
+        try {
+            return client.getAcsResponse(request);
+        } catch (Exception e) {
+            throw new RuntimeException("assume role error", e);
+        }
+    }
+}

+ 44 - 0
src/main/java/com/qmth/ops/aliyun/utils/SlsProject.java

@@ -0,0 +1,44 @@
+package com.qmth.ops.aliyun.utils;
+
+public class SlsProject {
+
+    private String group;
+
+    private String name;
+
+    private String project;
+
+    private String store;
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getProject() {
+        return project;
+    }
+
+    public void setProject(String project) {
+        this.project = project;
+    }
+
+    public String getStore() {
+        return store;
+    }
+
+    public void setStore(String store) {
+        this.store = store;
+    }
+}

+ 81 - 0
src/main/java/com/qmth/ops/aliyun/utils/SlsService.java

@@ -0,0 +1,81 @@
+package com.qmth.ops.aliyun.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
+import com.qmth.ops.aliyun.config.SlsConfig;
+import com.sun.deploy.net.URLEncoder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.PostConstruct;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class SlsService {
+
+    private List<SlsProject> projectList;
+
+    @Autowired
+    private SlsConfig config;
+
+    public List<SlsProject> getProject() {
+        return projectList;
+    }
+
+    public Mono<String> view(String project, String store) {
+        AssumeRoleResponse response = AssumeRoleClient.get(config);
+        Mono<String> token = getToken(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(),
+                response.getCredentials().getSecurityToken());
+        return getSignUrl(token, project, store);
+    }
+
+    private Mono<String> getToken(String accessKey, String accessSecret, String token) {
+        //String tokenUrl = MessageFormat.format(config.getTokenUrl(), param(accessKey), param(accessSecret), param(token));
+        return WebClient.create().get().uri(config.getTokenUrl(), accessKey, accessSecret, token).retrieve().bodyToMono(String.class)
+                .flatMap(body -> {
+                    JSONObject json = JSONObject.parseObject(body);
+                    String st = json.getString("SigninToken");
+                    return st != null ? Mono.just(st) : Mono.error(new RuntimeException("get SigninToken faile: " + body));
+                });
+    }
+
+    private Mono<String> getSignUrl(Mono<String> token, String project, String store) {
+        return token.flatMap(t -> Mono.just(MessageFormat.format(config.getSignUrl(), param(config.getRedirectUrl()),
+                param(MessageFormat.format(config.getQueryUrl(), project, store)), param(t))));
+    }
+
+    private static String param(String content) {
+        try {
+            return URLEncoder.encode(content, StandardCharsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            return "";
+        }
+    }
+
+    @PostConstruct
+    public void initProject() throws IOException {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(new ClassPathResource("sls-project.txt").getInputStream()));
+        projectList = new ArrayList<>();
+        String line = null;
+        while ((line = reader.readLine()) != null) {
+            String[] values = line.split(",");
+            SlsProject project = new SlsProject();
+            project.setGroup(values[0]);
+            project.setName(values[1]);
+            project.setProject(values[2]);
+            project.setStore(values[3]);
+            projectList.add(project);
+        }
+        reader.close();
+    }
+}

+ 16 - 0
src/main/resources/application.properties

@@ -0,0 +1,16 @@
+server.port=8080
+
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+
+
+sls.ramName=monitor
+sls.ramAssumeRole=acs:ram::30078572:role/monitor
+sls.accessKey=LTAI4GF81QrVMW8oiBg1YwmK
+sls.accessSecret=GFbqps8W87cOb3vna20IptoY0fcjXh
+sls.redirectUrl=https://ops.qmth.com.cn
+sls.queryUrl=https://sls4service.console.aliyun.com/next/project/{0}/logsearch/{1}?readOnly=true&hideSidebar=true&hideTopbar=true
+sls.tokenUrl=https://signin.aliyun.com/federation?Action=GetSigninToken&AccessKeyId={0}&AccessKeySecret={1}&SecurityToken={2}&TicketType=mini
+sls.signUrl=https://signin.aliyun.com/federation?Action=Login&LoginUrl={0}&Destination={1}&SigninToken={2}
+
+

+ 3 - 0
src/main/resources/sls-project.txt

@@ -0,0 +1,3 @@
+公共,支付中心,sae-68305dcf-2eeb-4597-95e8-89dbfad36dc6,sae-9429bced7d168c8ae38df8a19d95f1ac
+云平台,负载均衡,examcloud,slb
+逸教云,api-r1,sae-72670aa8-5707-485a-a373-96f633a6a638,sae-d81a9ba31d977b3245e4f81852f1630f