作者:俏巴
概述
日志服务(Log Service,简称 LOG)是针对日志类数据的一站式服务,在阿里巴巴集团经历大量大数据场景锤炼而成。用户除了通过管理控制台进行操作外,LOG 还提供了 API(Application Programming Interface)方式写入、查询日志数据,管理自己的项目及日志库等。在实际的开发使用过程中,我们建议用户使用官方提供的最新版SDK。直接使用Rest API相对比较麻烦,特别是在签名的生成过程中很容易出错,且不易排查。下面主要介绍CreateProject、DeleteProject和ListLogstore三个API的使用示例,相关示例使用JAVA语言。
相关依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
示例代码
CreateProject
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import java.math.BigInteger;
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
//创建project操作
public class CreateProject {
public static void main(String[] args){
//获取GMT英文格式时间
Date d=new Date();
DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = format.format(d);
//参数设置
String projectName = "restapiproject";//日志服务项目名称
String projectDescription = "sample_demo";//日志服务项目描述
String AccessKeySecret = "********";//Access Key Secret
String AccessKeyId = "********";//AccessKey ID
JSONObject jsonBody = new JSONObject();
jsonBody.put("projectName", projectName);
jsonBody.put("description", projectDescription);
//构造请求body
String body = jsonBody.toString();
System.out.println("jsonBody: " + jsonBody.toString());
String md5 = md5(body).toUpperCase();
md5 = md5.toUpperCase();//小写字母转大写
//构造签名String
String SignString = "POST\n" +
md5+"\n"+
"application/json\n" +
date + "\n"+
"x-log-apiversion:0.6.0\n" +
"x-log-bodyrawsize:0\n" +
"x-log-signaturemethod:hmac-sha1\n" + "/";
String sign = encode(AccessKeySecret,SignString);
String Authorization = "LOG " + AccessKeyId + ":" + sign;
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("http://"+projectName+".cn-qingdao.log.aliyuncs.com");//在青岛区域创建Project
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Authorization", Authorization);
request.setHeader("Date", date);
request.setHeader("Host", projectName + ".cn-qingdao.log.aliyuncs.com");
request.setHeader("x-log-apiversion", "0.6.0");
request.setHeader("x-log-signaturemethod", "hmac-sha1");
request.setHeader("Content-Type","application/json");
request.setHeader("User-Agent","sls-java-sdk-v-0.6.1");
request.setHeader("x-log-bodyrawsize","0");
request.setHeader("Content-MD5", md5);
// Request body
StringEntity reqEntity = new StringEntity(body,"UTF-8");
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println("项目创建成功!");
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println("error");
System.out.println(e.getMessage());
}
}
//写一个md5加密的方法
public static String md5(String plainText) {
//定义一个字节数组
byte[] secretBytes = null;
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
//对字符串进行加密
md.update(plainText.getBytes());
//获得加密后的数据
secretBytes = md.digest();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
//将加密后的数据转换为16进制数字
String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
// 如果生成数字未满32位,需要前面补0
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
//计算签名
public static String encode(String accessKey, String data) {
try {
byte[] keyBytes = accessKey.getBytes("UTF-8");
byte[] dataBytes = data.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
} catch (UnsupportedEncodingException var5) {
throw new RuntimeException("Not supported encoding method UTF-8", var5);
} catch (NoSuchAlgorithmException var6) {
throw new RuntimeException("Not supported signature method hmac-sha1", var6);
} catch (InvalidKeyException var7) {
throw new RuntimeException("Failed to calculate the signature", var7);
}
}
}
Delete Project
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URI;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
//删除project的操作
public class DeleProject {
public static void main(String[] args){
//获取GMT英文格式时间
Date d=new Date();
DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = format.format(d);
String AccessKeySecret = "********";
String AccessKeyId = "********";
String projectName = "restapiproject";//删除的project名称
String SignString = "DELETE\n" +
"\n"+
"application/x-protobuf\n" +
date + "\n"+
"x-log-apiversion:0.6.0\n" +
"x-log-bodyrawsize:0\n" +
"x-log-signaturemethod:hmac-sha1\n"+"/";
String sign = encode(AccessKeySecret,SignString);
String Authorization = "LOG " + AccessKeyId + ":" + sign;
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("http://"+projectName+".cn-qingdao.log.aliyuncs.com/");
URI uri = builder.build();
HttpDelete request = new HttpDelete(uri);
request.setHeader("Authorization", Authorization);
request.setHeader("Date", date);
request.setHeader("Host", projectName + ".cn-qingdao.log.aliyuncs.com");
request.setHeader("x-log-apiversion", "0.6.0");
request.setHeader("x-log-signaturemethod", "hmac-sha1");
request.setHeader("Content-Type","application/x-protobuf");
request.setHeader("User-Agent","sls-java-sdk-v-0.6.1");
request.setHeader("x-log-bodyrawsize","0");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
//写一个md5加密的方法
public static String md5(String plainText) {
//定义一个字节数组
byte[] secretBytes = null;
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
//对字符串进行加密
md.update(plainText.getBytes());
//获得加密后的数据
secretBytes = md.digest();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
//将加密后的数据转换为16进制数字
String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
// 如果生成数字未满32位,需要前面补0
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
public static String encode(String accessKey, String data) {
try {
byte[] keyBytes = accessKey.getBytes("UTF-8");
byte[] dataBytes = data.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
} catch (UnsupportedEncodingException var5) {
throw new RuntimeException("Not supported encoding method UTF-8", var5);
} catch (NoSuchAlgorithmException var6) {
throw new RuntimeException("Not supported signature method hmac-sha1", var6);
} catch (InvalidKeyException var7) {
throw new RuntimeException("Failed to calculate the signature", var7);
}
}
}
ListLogstore
import org.apache.commons.codec.binary.Base64;
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
//列出指定项目Project下面的日志库
public class GetProjectLogstores {
public static void main(String[] args){
//获取GMT英文格式时间
Date d=new Date();
DateFormat format=new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",Locale.ENGLISH);//英文格式的时间转换时需要带上Locale.ENGLISH,否则会转换失败,因为它默认的是本地化的设置,除非你的操作系统是英文的,总之时间转换时需要时间格式与模式保持一致。
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = format.format(d);
//参数设置
String projectName = "taroslproject";//项目名称
String AccessKeySecret = "********";
String AccessKeyId = "********";
String SignString = "GET\n" +
"\n" +
"application/x-protobuf\n" +
date + "\n"+
"x-log-apiversion:0.6.0\n" +
"x-log-bodyrawsize:0\n" +
"x-log-signaturemethod:hmac-sha1\n" +
"/logstores?logstoreName=&offset=0&size=100";
String sign = encode(AccessKeySecret,SignString);
String Authorization = "LOG " + AccessKeyId + ":" + sign;
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("http://"+projectName+".cn-qingdao.log.aliyuncs.com/logstores");
builder.setParameter("offset", "0");
builder.setParameter("size", "100");
builder.setParameter("logstoreName", "");
URI uri = builder.build();
HttpGet request = new HttpGet(uri);
request.setHeader("Authorization", Authorization);
request.setHeader("Date", date);
request.setHeader("Host", projectName + ".cn-qingdao.log.aliyuncs.com");
request.setHeader("x-log-apiversion", "0.6.0");
request.setHeader("x-log-signaturemethod", "hmac-sha1");
request.setHeader("Content-Length","0");
request.setHeader("Content-Type","application/x-protobuf");
request.setHeader("User-Agent","sls-java-sdk-v-0.6.1");
request.setHeader("x-log-bodyrawsize","0");
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
System.out.println(EntityUtils.toString(entity));
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
public static String encode(String accessKey, String data) {
try {
byte[] keyBytes = accessKey.getBytes("UTF-8");
byte[] dataBytes = data.getBytes("UTF-8");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(new SecretKeySpec(keyBytes, "HmacSHA1"));
return new String(Base64.encodeBase64(mac.doFinal(dataBytes)));
} catch (UnsupportedEncodingException var5) {
throw new RuntimeException("Not supported encoding method UTF-8", var5);
} catch (NoSuchAlgorithmException var6) {
throw new RuntimeException("Not supported signature method hmac-sha1", var6);
} catch (InvalidKeyException var7) {
throw new RuntimeException("Failed to calculate the signature", var7);
}
}
}
建议
在实际的使用过程中,当必须要直接使用Rest API,如果仅仅参考API的文档说明,测试出现问题的时候排查比较困难。目前Java语言的SDK实现了全部的API,建议可以参考Java SDK的源码编写自己的功能函数。