NEZ-902 nz-talon 增加 promtail 代理接口

This commit is contained in:
hyx
2021-08-10 11:09:35 +08:00
parent 70da6cb473
commit 97b385e65e

View File

@@ -1,6 +1,12 @@
package net.geedge.confagent.controller;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.net.url.UrlPath;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpConnection;
import cn.hutool.log.Log;
import net.geedge.confagent.annotation.UnCheckToken;
import net.geedge.confagent.util.ConfagentUtil;
import net.geedge.confagent.util.R;
import net.geedge.confagent.util.RCode;
@@ -11,8 +17,18 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.*;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/promtail")
public class PromtailController extends BaseController{
@@ -36,6 +52,8 @@ public class PromtailController extends BaseController{
@Value("${confagent.promtail.stopCmd:systemctl stop promtail.service}")
private String stopCmd;
private final String[] QUERY_API_SUFFIX = {"query","query_range","series","labels","label","values"};
private static String rootPath = Tool.WebPathUtil.getRootPath();
/**
@@ -148,16 +166,104 @@ public class PromtailController extends BaseController{
}
// private boolean reloadPromtail(){
//
// UrlBuilder promtailReload = new UrlBuilder();
// int promtailPort = ConfagentUtil.getConfFilePort(promtailCmdLinePath, PROMTAIL_LISTEN_ADDR, DEFAULT_PROMTAIL_PORT);
// promtailReload.setScheme("http").setHost(defaultPromtailIP).setPort(promtailPort).addPath("/-/reload");
//
// String url = promtailReload.toString();
// HttpRequest post = Tool.HttpUtil.createPost(url);
// HttpResponse response = post.execute();
// return 200 == response.getStatus();
// }
/**
* @Description 代理本promtail 接口
* @Author han
* @Date 2021/8/10
*/
@RequestMapping("/proxy/**")
@UnCheckToken
public void proxy(HttpServletRequest request, HttpServletResponse response){
String promtailPath = request.getServletPath().replace("/promtail/proxy","");
String token = request.getHeader("Authorization");
R r = confagentUtil.checkToken(token);
Boolean isQuery=false;
//queryAuth 配置只限制查询是否需要校验
if(queryAuth){
isQuery = Tool.StrUtil.isNotBlank(Arrays.stream(QUERY_API_SUFFIX).filter(t -> promtailPath.indexOf(t) != -1).findAny().orElse(null));
}
if(isQuery &&r.getCode() != RCode.SUCCESS.getCode()){
ConfagentUtil.writeResponse(response,r);
return;
}
int port = 9080;
Map<String,Object> promtailMap= Tool.YamlUtil.readAsMap(promtailConfPath);
Map<String,Object> serverObj = (Map<String,Object>)promtailMap.get("server");
if(serverObj!=null) {
port = (Integer)serverObj.get("http_listen_port");
}
requestProm(defaultPromtailIP,port,promtailPath,request,response);
}
public void requestProm(String host, int port, String path, HttpServletRequest request, HttpServletResponse response) {
String queryString = ReflectUtil.invoke(request, "getQueryString");
queryString = StrUtil.isNotBlank(queryString)?queryString:"";
String url = UrlBuilder.create().setScheme("http").setHost(host).setPort(port).setPath(UrlPath.of(path, Charset.forName("UTF-8"))).toURL().toString() + "?" + queryString;
log.info("promtail url: {}", url);
String method = request.getMethod();
HttpURLConnection conn = null;
ServletInputStream reqInputStream = null;
ServletOutputStream resOutputStream = null;
OutputStream connOutputStream = null;
InputStream connInputStream = null;
try {
conn = HttpConnection.create(url, null).getHttpURLConnection();
reqInputStream = request.getInputStream();
resOutputStream = response.getOutputStream();
conn.setRequestMethod(method);
// 复制请求头
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String hn = headerNames.nextElement();
if(!"authorization".equalsIgnoreCase(hn)) {
ReflectUtil.invoke(conn,"addRequestProperty",hn,request.getHeader(hn));
}
}
if (!"GET".equalsIgnoreCase(method)) {
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
connOutputStream = conn.getOutputStream();
Tool.IoUtil.copy(reqInputStream, connOutputStream);
}
conn.connect();
int responseCode = conn.getResponseCode();
connInputStream = (responseCode < 400)? conn.getInputStream():conn.getErrorStream();
String responseMessage = conn.getResponseMessage();
Map<String, List<String>> responseHeaders = conn.getHeaderFields();
//复制响应头
for(Map.Entry<String, List<String>> en : responseHeaders.entrySet()) {
String key = en.getKey();
if (Tool.StrUtil.isEmpty(key) || "Transfer-Encoding".equals(key)) continue;
List<String> value = en.getValue();
ReflectUtil.invoke(response,"addHeader",key,Tool.StrUtil.join("; ",value));
}
ReflectUtil.invoke(response, "setStatus", responseCode, responseMessage);
Tool.IoUtil.copy(connInputStream, resOutputStream);
resOutputStream.flush();//flush 输出流
} catch (Exception e) {
try {
response.sendError(500, "request error");
} catch (IOException e1) {
log.error("proxy request error",e1);
}
log.error("request error : ",e);
}finally {
Tool.IoUtil.close(reqInputStream,resOutputStream,connOutputStream,connInputStream);
if(conn != null){
conn.disconnect();
}
}
}
}