Merge branch 'Operationlog' into github_dev

This commit is contained in:
fanqq 2015-07-20 18:10:36 +08:00
commit bcd24371a3
19 changed files with 827 additions and 14 deletions

View file

@ -275,6 +275,7 @@
${basedir}/src/main/resources/META-INF/dal/model/message-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/auth-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/report-manifest.xml,
${basedir}/src/main/resources/META-INF/dal/model/operationlog-manifest.xml,
]]></manifest>
</configuration>
</execution>

View file

@ -1,14 +0,0 @@
package com.ctrip.zeus.access;
import java.lang.annotation.*;
/**
* Created by fanqq on 2015/7/15.
*/
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AccessAnnotation {
}

View file

@ -0,0 +1,62 @@
package com.ctrip.zeus.restful.resource;
import com.ctrip.zeus.operationlog.entity.OperationLogData;
import com.ctrip.zeus.operationlog.entity.OperationLogDataList;
import com.ctrip.zeus.restful.message.ResponseHandler;
import com.ctrip.zeus.service.operationLog.OperationLogService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by fanqq on 2015/7/20.
*/
@Component
@Path("/logs")
public class OperationLogResource {
@Resource
private OperationLogService operationLogService;
@Resource
private ResponseHandler responseHandler;
@GET
@Path("/")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response logs(@Context HttpServletRequest request,
@Context HttpHeaders hh ,
@QueryParam("type")String type,
@QueryParam("targetId")String targetId,
@QueryParam("op")String op,
@QueryParam("user")String user,
@QueryParam("clientIp")String clientIp,
@QueryParam("success")Boolean success,
@QueryParam("fromDate")String from,
@QueryParam("toDate")String to,
@QueryParam("count")Long count
) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
Date fromDate = null;
Date toDate = null;
if (from !=null){
fromDate= sdf.parse(from);
}
if (to != null) {
toDate = sdf.parse(to);
}
OperationLogDataList result = operationLogService.find(type,targetId,op,user,clientIp,success,fromDate,toDate,count);
String a = String.format(OperationLogDataList.JSON,result);
System.out.print(a);
return responseHandler.handle(result,hh.getMediaType());
}
}

View file

@ -17,4 +17,5 @@ public class AspectOrder {
public static int CatReport = 3;
public static int MessageReport = 1;
public static int Authorization = 100;
public static int Access = 150;
}

View file

@ -0,0 +1,91 @@
package com.ctrip.zeus.service.aop.OperationLog;
import java.util.HashMap;
/**
* Created by fanqq on 2015/7/16.
*/
public class OperationLogConfig {
private static HashMap<String,OpConf> config = new HashMap<>();
private static OperationLogConfig logConfig = new OperationLogConfig();
private OperationLogConfig() {
loadConfig();
}
private void loadConfig(){
config.put("ActivateResource.activateSlb",new OpConf(OperationLogType.SLB,new int[]{2,3}));
config.put("ActivateResource.activateGroup",new OpConf(OperationLogType.GROUP,new int[]{2,3}));
config.put("DeactivateResource.deactivateGroup",new OpConf(OperationLogType.GROUP,new int[]{2,3}));
config.put("GroupResource.list",new OpConf(OperationLogType.GROUP,null,true));
config.put("GroupResource.get",new OpConf(OperationLogType.GROUP,new int[]{2,3}));
config.put("GroupResource.add",new OpConf(OperationLogType.GROUP,new int[]{-1,2}));
config.put("GroupResource.update",new OpConf(OperationLogType.GROUP,new int[]{2}));
config.put("GroupResource.delete",new OpConf(OperationLogType.GROUP,new int[]{2}));
config.put("SlbResource.list",new OpConf(OperationLogType.SLB,null,true));
config.put("SlbResource.get",new OpConf(OperationLogType.SLB,new int[]{2,3}));
config.put("SlbResource.add",new OpConf(OperationLogType.SLB,new int[]{-1,2}));
config.put("SlbResource.update",new OpConf(OperationLogType.SLB,new int[]{2}));
config.put("SlbResource.delete",new OpConf(OperationLogType.SLB,new int[]{2}));
config.put("ServerResource.upServer",new OpConf(OperationLogType.SERVER,new int[]{2}));
config.put("ServerResource.downServer",new OpConf(OperationLogType.SERVER,new int[]{2}));
config.put("ServerResource.upMember",new OpConf(OperationLogType.SERVER,new int[]{2,3}));
config.put("ServerResource.downMember",new OpConf(OperationLogType.SERVER,new int[]{2,3}));
config.put("StatusResource.allGroupStatusInSlb",new OpConf(OperationLogType.SLB,new int[]{2,3}));
config.put("StatusResource.groupStatus",new OpConf(OperationLogType.GROUP,new int[]{2,3}));
}
public static OperationLogConfig getInstance(){return logConfig;}
public OperationLogType getType(String key){
OpConf tmp = config.get(key);
if (tmp != null){
return tmp.getType();
}
return null;
}
public int[] getIds(String key){
OpConf tmp = config.get(key);
if (tmp != null){
return tmp.getId();
}
return null;
}
public boolean getBatch(String key){
OpConf tmp = config.get(key);
if (tmp != null){
return tmp.getBatch();
}
return false;
}
public boolean contain(String key){
if (config.get(key)==null){
return false;
}
return true;
}
class OpConf{
private OperationLogType type;
private int[] id;
private boolean batch;
OpConf(OperationLogType _type , int[]_id , boolean _batch){
type = _type;
id = _id;
batch = _batch;
}
OpConf(OperationLogType _type , int[]_id){
type = _type;
id = _id;
batch = false;
}
protected int[] getId(){return id;}
protected OperationLogType getType(){return type;}
protected boolean getBatch(){return batch;}
}
}

View file

@ -0,0 +1,16 @@
package com.ctrip.zeus.service.aop.OperationLog;
/**
* Created by fanqq on 2015/7/16.
*/
public enum OperationLogType {
SLB,
GROUP,
SERVER;
public String value() {
return name();
}
public static OperationLogType fromValue(String v) {
return valueOf(v);
}
}

View file

@ -0,0 +1,358 @@
package com.ctrip.zeus.service.aop;
import com.ctrip.zeus.model.entity.Group;
import com.ctrip.zeus.model.entity.Slb;
import com.ctrip.zeus.model.transform.DefaultJsonParser;
import com.ctrip.zeus.model.transform.DefaultSaxParser;
import com.ctrip.zeus.service.aop.OperationLog.OperationLogConfig;
import com.ctrip.zeus.service.aop.OperationLog.OperationLogType;
import com.ctrip.zeus.service.model.GroupRepository;
import com.ctrip.zeus.service.model.SlbRepository;
import com.ctrip.zeus.service.operationLog.OperationLogService;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* Created by fanqq on 2015/7/15.
*/
@Aspect
@Component
public class OperationLogAspect implements Ordered {
@Resource
private GroupRepository groupRepository;
@Resource
private SlbRepository slbRepository;
@Resource
private OperationLogService operationLogService;
private final static String QUERY_NAME_SLB_ID="slbId";
private final static String QUERY_NAME_SLB_NAME="slbName";
private final static String QUERY_NAME_GROUP_ID="groupId";
private final static String QUERY_NAME_GROUP_NAME="groupName";
private final static String ID_NEW="New";
private final static String ID_UNKNOW="Unknow";
private final static String ID_BATCH="Batch";
private Logger logger = LoggerFactory.getLogger(this.getClass());
private DynamicBooleanProperty enableAccess = DynamicPropertyFactory.getInstance().getBooleanProperty("log.access.enable", true);
@Around("execution(* com.ctrip.zeus.restful.resource.*Resource.*(..))")
public Object interceptException(ProceedingJoinPoint point) throws Throwable {
if (!enableAccess.get()){
return point.proceed();
}
String type = null;
String id =null;
String op = null;
String userName = null;
String remoteAddr = null;
HashMap<String,String> data = new HashMap<>();
Object response = null;
String errMsg = null;
boolean success = false;
HttpServletRequest request = findRequestArg(point);
if (request==null){
return point.proceed();
}
MethodSignature signature = (MethodSignature)point.getSignature();
Method method = signature.getMethod();
String key = point.getTarget().getClass().getSimpleName()+"."+method.getName();
if (!OperationLogConfig.getInstance().contain(key)){
return point.proceed();
}
try {
Object[] args = point.getArgs();
Annotation[][] annotations = method.getParameterAnnotations();
HttpHeaders hh = findHttpHeaders(point);
type = OperationLogConfig.getInstance().getType(key).value();
id = findId(key,request,args,point,hh);
op = method.getName();
userName = request.getRemoteUser();
remoteAddr = request.getRemoteAddr();
data = findData(key,request,args,hh,method);
}catch (Exception e){
logger.warn("Operation Log Aspect Exception!"+e.getMessage());
}
try{
response = point.proceed();
}catch (Throwable throwable){
errMsg = throwable.getMessage();
throw throwable;
}finally {
if (response!=null){
success=true;
}
operationLogService.insert(type,id,op,data.toString(),userName,remoteAddr,success,errMsg,new Date());
}
return response;
}
@Override
public int getOrder() {
return AspectOrder.Access;
}
private HttpServletRequest findRequestArg(JoinPoint point) {
Object[] args = point.getArgs();
for (Object arg : args) {
if (arg instanceof HttpServletRequest){
return (HttpServletRequest)arg;
}
}
return null;
}
private HttpHeaders findHttpHeaders(JoinPoint point){
Object[] args = point.getArgs();
for (Object arg : args) {
if (arg instanceof HttpHeaders){
return (HttpHeaders)arg;
}
}
return null;
}
private String findId(String key,HttpServletRequest request ,Object[] args ,JoinPoint point,HttpHeaders hh) throws Exception {
//1. Batch is true, return "Batch"
if (OperationLogConfig.getInstance().getBatch(key)){
return ID_BATCH;
}
// find by config ids
int[]ids = OperationLogConfig.getInstance().getIds(key);
for (int i : ids)
{
//2. if id is out of range , return New
if (i<0||i>=args.length)
{
return ID_NEW;
}
//3. if request Method is Post , Parse post data to get id
if (request.getMethod().equals("POST")&&null!=args[i])
{
// 3.1 httpHeaders is null , Can not parse post data;
if (null == hh){
return ID_UNKNOW;
}
// 3.2 type is AccessType.SLB , parse data to Slb object.
if (OperationLogConfig.getInstance().getType(key)== OperationLogType.SLB){
Slb slb = parseSlb(hh.getMediaType(),(String)args[i]);
if (slb == null){
return ID_UNKNOW;//"Slb Parse Fail";
}
return slb.getId()!=null?String.valueOf(slb.getId()):slb.getName();
}
// 3.3 type is AccessType.GROUP , parse data to Group object.
if (OperationLogConfig.getInstance().getType(key)==OperationLogType.GROUP){
Group group = parseGroup(hh.getMediaType(),(String)args[i]);
if (group == null){
return ID_UNKNOW;//"Group Parse Fail";
}
return group.getId()!=null?String.valueOf(group.getId()):group.getName();
}
return ID_UNKNOW;
}
// 4. if method is GET , find id from args. Type Long comes first.
if (null!=args[i])
{
String name = null;
if (args[i] instanceof String)
{
name = (String)args[i];
}
if (args[i] instanceof Long)
{
return String.valueOf((Long)args[i]);
}
if (args[i] instanceof List<?>)
{
List tmp = (List)args[i];
if (tmp.size()>1){
return ID_BATCH;
}else if (tmp.size()==1){
if (tmp.get(0) instanceof String){
name=(String)tmp.get(0);
}else {
return tmp.get(0).toString();
}
}
}
if (OperationLogConfig.getInstance().getType(key)==OperationLogType.GROUP&&name!=null)
{
Group group =groupRepository.get(name);
return group==null?name:String.valueOf(group.getId());
}else if (OperationLogConfig.getInstance().getType(key)==OperationLogType.SLB&&name!=null){
Slb slb =slbRepository.get(name);
return slb==null?name:String.valueOf(slb.getId());
}else if (name!=null){
return name;
}
}
}
return ID_UNKNOW;
}
private HashMap<String,String> findData(String key , HttpServletRequest request ,Object[] args ,HttpHeaders hh,Method method) throws Exception {
HashMap<String,String>data = new HashMap<>();
int[] ids = OperationLogConfig.getInstance().getIds(key);
Annotation[][] annotations = method.getParameterAnnotations();
//1. request Method is Post, data should be Name and Version
if (request.getMethod().equals("POST")){
if (ids==null||ids.length<=0){
return data;
}
//1.1 in case of New
if (ids.length>0&&(ids[0]<0||ids[0]>=args.length))
{
data.put("SlbVersion","1");
if (ids.length>=2&&args[ids[1]] instanceof String)
{
String postData = (String)args[ids[1]];
if (OperationLogConfig.getInstance().getType(key)==OperationLogType.SLB&&hh!=null){
Slb slb = parseSlb(hh.getMediaType(),postData);
if (slb==null){
data.put("Slb","Slb Parse Fail!");
}else {
data.put("SlbName",String.valueOf(slb.getName()));
}
}else if (OperationLogConfig.getInstance().getType(key)==OperationLogType.GROUP&&hh!=null){
Group group = parseGroup(hh.getMediaType(),postData);
if (group==null){
data.put("Group","Group Parse Fail!");
}else{
data.put("GroupName",String.valueOf(group.getName()));
}
}
}
return data;
}
//1.2 in case of update
Object obj = args[ids[0]];
String tmp = null;
if (obj instanceof String){
tmp=(String)obj;
}else {
data.put("errMsg",ids[0]+"'st argument is not String");
return data;
}
if (OperationLogConfig.getInstance().getType(key)==OperationLogType.SLB&&hh!=null){
Slb slb = parseSlb(hh.getMediaType(),tmp);
if (slb==null){
data.put("Slb","Slb Parse Fail!");
}else {
data.put("SlbName",String.valueOf(slb.getName()));
data.put("Version",String.valueOf(slb.getVersion()));
}
}else if (OperationLogConfig.getInstance().getType(key)==OperationLogType.GROUP&&hh!=null){
Group group = parseGroup(hh.getMediaType(),tmp);
if (group==null){
data.put("Group","Group Parse Fail!");
}else{
data.put("GroupName",String.valueOf(group.getName()));
data.put("Version",String.valueOf(group.getVersion()));
}
}
return data;
}else {
//2. request method is GET, get data from QueryString
String tmpKey = null;
for (int i=0; i < args.length;i++)
{
if (annotations[i][0] instanceof QueryParam){
//1. get queryParam Names
tmpKey = ((QueryParam)annotations[i][0]).value();
//2. queryParam Names equals QUERY_NAME_GROUP_ID , must be groupId.
if (tmpKey.equalsIgnoreCase(QUERY_NAME_GROUP_ID)&&args[i]!=null) {
if (args[i] instanceof Long) {
Group group = groupRepository.getById((Long)args[i]);
data.put(OperationLogType.GROUP.value(),group!=null?group.getName():args[i].toString()+"[id not found]");
}
if (args[i] instanceof List) {
List list = (List)args[i];
List<String> groupNames = new ArrayList<>();
for (Object groupId : list){
Group group = groupRepository.getById((Long)groupId);
groupNames.add(group!=null?group.getName():groupId.toString()+"[id not found]");
}
if (groupNames.size()>0) {
data.put(OperationLogType.GROUP.value(), groupNames.toString());
}
}
}else if (tmpKey.equalsIgnoreCase(QUERY_NAME_SLB_ID)&&args[i]!=null) {
if (args[i] instanceof Long) {
Slb slb = slbRepository.getById((Long)args[i]);
data.put(OperationLogType.SLB.value(),slb!=null?slb.getName():args[i].toString()+"[id not found]");
}
if (args[i] instanceof List) {
List list = (List)args[i];
List<String> slbNames = new ArrayList<>();
for (Object slbId : list){
Slb slb = slbRepository.getById((Long)slbId);
slbNames.add(slb!=null?slb.getName():slbId.toString()+"[id not found]");
}
if (slbNames.size()>0){
data.put(OperationLogType.SLB.value(),slbNames.toString());
}
}
}else if (args[i]!=null){
if (args[i] instanceof List&&((List)args[i]).size()>0||args[i] instanceof Long || args[i] instanceof String){
data.put(tmpKey,args[i].toString());
}
}
}
}
return data;
}
}
private Group parseGroup(MediaType mediaType, String group) {
Group g;
try{
if (mediaType.equals(MediaType.APPLICATION_XML_TYPE)) {
g = DefaultSaxParser.parseEntity(Group.class, group);
} else {
g = DefaultJsonParser.parse(Group.class, group);
}
}catch (Exception e) {
logger.warn("Group Parse Fail!");
return null;
}
return g;
}
private Slb parseSlb(MediaType mediaType, String slb) {
Slb s;
try{
if (mediaType.equals(MediaType.APPLICATION_XML_TYPE)) {
s = DefaultSaxParser.parseEntity(Slb.class, slb);
} else {
s = DefaultJsonParser.parse(Slb.class, slb);
}
}catch (Exception e) {
logger.warn("Slb Parse Fail!");
return null;
}
return s;
}
}

View file

@ -0,0 +1,14 @@
package com.ctrip.zeus.service.operationLog;
import com.ctrip.zeus.operationlog.entity.OperationLogDataList;
import java.util.Date;
/**
* Created by fanqq on 2015/7/20.
*/
public interface OperationLogService {
public void insert(String type,String targetId,String operation , String data,
String user , String clientIp,boolean success,String errMsg , Date dateTime );
public OperationLogDataList find(String type,String targetId,String operation ,
String user , String clientIp,Boolean success, Date fromDateTime ,Date toDateTime , Long count) throws Exception;
}

View file

@ -0,0 +1,92 @@
package com.ctrip.zeus.service.operationLog.impl;
import com.ctrip.zeus.dal.core.OperationLogDao;
import com.ctrip.zeus.dal.core.OperationLogDo;
import com.ctrip.zeus.dal.core.OperationLogEntity;
import com.ctrip.zeus.operationlog.entity.OperationLogData;
import com.ctrip.zeus.operationlog.entity.OperationLogDataList;
import com.ctrip.zeus.service.operationLog.OperationLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.unidal.dal.jdbc.DalException;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by fanqq on 2015/7/20.
*/
@Component("operationLogService")
public class OperationLogServiceImpl implements OperationLogService {
@Resource
private OperationLogDao operationLogDao;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void insert(String type,String targetId,String operation , String data,
String user , String clientIp,boolean success,String errMsg , Date dateTime) {
OperationLogDo operationLogDo = new OperationLogDo();
if (type!=null){
operationLogDo.setType(type);
}
if (targetId !=null){
operationLogDo.setTargetId(targetId);
}
if (operation !=null){
operationLogDo.setOperation(operation);
}
if (data !=null){
operationLogDo.setData(data);
}
if (user !=null){
operationLogDo.setUserName(user);
}
if (clientIp !=null){
operationLogDo.setClientIp(clientIp);
}
if (errMsg !=null){
operationLogDo.setErrMsg(errMsg);
}
if (dateTime !=null){
operationLogDo.setDatetime(dateTime);
}
operationLogDo.setSuccess(success);
try {
operationLogDao.insert(operationLogDo);
} catch (DalException e) {
logger.warn("OperationLog DalException! "+e.getMessage());
}
}
@Override
public OperationLogDataList find(String type,String targetId,String operation ,
String user , String clientIp,Boolean success, Date fromDateTime ,Date toDateTime , Long count) throws Exception {
List<OperationLogDo> res = null;
Long limitCount = count == null?1000L:count;
if (success==null){
res = operationLogDao.findByOptions(type,targetId,operation,user,clientIp,fromDateTime,toDateTime,limitCount, OperationLogEntity.READSET_FULL);
}else {
res = operationLogDao.findByOptionsWithSuccess(type,targetId,operation,user,clientIp,success,fromDateTime,toDateTime,limitCount, OperationLogEntity.READSET_FULL);
}
OperationLogDataList result = new OperationLogDataList();
if (res == null)return result;
OperationLogData tmp = null;
for (OperationLogDo logDo : res){
tmp = new OperationLogData();
tmp.setClientIp(logDo.getClientIp())
.setErrMsg(logDo.getErrMsg())
.setData(logDo.getData())
.setDateTime(logDo.getDatetime())
.setOperation(logDo.getOperation())
.setTargetId(logDo.getTargetId())
.setType(logDo.getType())
.setSuccess(logDo.isSuccess())
.setUserName(logDo.getUserName());
result.addOperationLogData(tmp);
}
return result;
}
}

View file

@ -908,6 +908,51 @@
</query>
</query-defs>
</entity>
<entity name="operation-log" table="operation_log" alias="ol">
<member name="id" field="id" value-type="long" length="19" nullable="false" key="true" auto-increment="true" />
<member name="type" field="type" value-type="String" length="128" nullable="false" />
<member name="target-id" field="target_id" value-type="String" length="128" nullable="false" />
<member name="operation" field="operation" value-type="String" length="128" nullable="false" />
<member name="data" field="data" value-type="String" length="10240" />
<member name="user-name" field="user_name" value-type="String" length="128" />
<member name="client-ip" field="client_ip" value-type="String" length="128" />
<member name="success" field="success" value-type="boolean" nullable="false" />
<member name="err-msg" field="err_msg" value-type="String" length="1024" />
<member name="datetime" field="datetime" value-type="Date" nullable="false" />
<member name="data-change-last-time" field="DataChange_LastTime" value-type="Date" nullable="false" />
<var name="key-id" value-type="long" key-member="id" />
<primary-key name="PRIMARY" members="id" />
<index name="DataChange_LastTime" members="DataChange_LastTime ASC" />
<readsets>
<readset name="FULL" all="true" />
</readsets>
<updatesets>
<updateset name="FULL" all="true" />
</updatesets>
<query-defs>
<query name="find-by-PK" type="SELECT">
<param name="key-id" />
<statement><![CDATA[SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
<query name="insert" type="INSERT">
<statement><![CDATA[INSERT INTO <TABLE/>(<FIELDS/>)
VALUES(<VALUES/>)]]></statement>
</query>
<query name="update-by-PK" type="UPDATE">
<param name="key-id" />
<statement><![CDATA[UPDATE <TABLE/>
SET <FIELDS/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
<query name="delete-by-PK" type="DELETE">
<param name="key-id" />
<statement><![CDATA[DELETE FROM <TABLE/>
WHERE <FIELD name='id'/> = ${key-id}]]></statement>
</query>
</query-defs>
</entity>
<entity name="report" table="report" alias="r">
<member name="group-id" field="group_id" value-type="long" length="19" nullable="false" key="true" />
<member name="status" field="status" value-type="int" length="10" nullable="false" />

View file

@ -9,5 +9,6 @@
<file path="core-lock.xml"/>
<file path="core-auth.xml"/>
<file path="core-report.xml"/>
<file path="core-operationlog.xml"/>
</manifest>

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<entities do-package="com.ctrip.zeus.dal.core" gen="true" do-class-suffix="Do">
<entity name="operation-log" table="operation_log" alias="ol">
<var name="from-datetime" value-type="Date"/>
<var name="to-datetime" value-type="Date"/>
<var name="count" value-type="Long"/>
<query-defs>
<query name="find-by-id" type="SELECT">
<param name="id"/>
<statement>
<![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE <FIELD name='id'/> = ${id}
]]>
</statement>
</query>
<query name="find-by-options" type="SELECT" multiple="true">
<param name="type"/>
<param name="target-id"/>
<param name="operation"/>
<param name="user-name"/>
<param name="client-ip"/>
<param name="from-datetime"/>
<param name="to-datetime"/>
<param name="count"/>
<statement>
<![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE (CASE WHEN ${type} IS NULL OR <FIELD name='type'/> = ${type} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${target-id} IS NULL OR <FIELD name='target-id'/> = ${target-id} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${operation} IS NULL OR <FIELD name='operation'/> = ${operation} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${user-name} IS NULL OR <FIELD name='user-name'/> = ${user-name} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${client-ip} IS NULL OR <FIELD name='client-ip'/> = ${client-ip} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${from-datetime} IS NULL OR <FIELD name='datetime'/> >= ${from-datetime} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${to-datetime} IS NULL OR <FIELD name='datetime'/> <= ${to-datetime} THEN TRUE ELSE FALSE END)
LIMIT ${count}
]]>
</statement>
</query>
<query name="find-by-options-with-success" type="SELECT" multiple="true">
<param name="type"/>
<param name="target-id"/>
<param name="operation"/>
<param name="user-name"/>
<param name="client-ip"/>
<param name="success"/>
<param name="from-datetime"/>
<param name="to-datetime"/>
<param name="count"/>
<statement>
<![CDATA[
SELECT <FIELDS/>
FROM <TABLE/>
WHERE (CASE WHEN ${type} IS NULL OR <FIELD name='type'/> = ${type} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${target-id} IS NULL OR <FIELD name='target-id'/> = ${target-id} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${operation} IS NULL OR <FIELD name='operation'/> = ${operation} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${user-name} IS NULL OR <FIELD name='user-name'/> = ${user-name} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${client-ip} IS NULL OR <FIELD name='client-ip'/> = ${client-ip} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${from-datetime} IS NULL OR <FIELD name='datetime'/> >= ${from-datetime} THEN TRUE ELSE FALSE END)
AND (CASE WHEN ${to-datetime} IS NULL OR <FIELD name='datetime'/> <= ${to-datetime} THEN TRUE ELSE FALSE END)
AND <FIELD name='success'/> = ${success}
LIMIT ${count}
]]>
</statement>
</query>
</query-defs>
</entity>
</entities>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<model>
<entity name="operationlog" root="true">
<entity-ref name="operation-log-data-list" />
</entity>
<entity name="operation-log-data-list">
<element name="total" value-type="int" />
<entity-ref name="operation-log-data" type="list" names="operation-log-datas" />
</entity>
<entity name="operation-log-data">
<element name="type" value-type="String" />
<element name="target-id" value-type="String" />
<element name="operation" value-type="String" />
<element name="user-name" value-type="String" />
<element name="data" value-type="String" />
<element name="client-ip" value-type="String" />
<element name="success" value-type="boolean" />
<element name="err-msg" value-type="String" />
<element name="date-time" value-type="Date" format="yyyy-MM-dd HH:mm:ss" />
</entity>
</model>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<file path="operationlog-codegen.xml" />
<file path="operationlog-model.xml" />
</manifest>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<model model-package="com.ctrip.zeus.operationlog" enable-sax-parser="true" enable-json-parser="true"
enable-json-builder="true"/>

View file

@ -206,6 +206,15 @@
<data-source-name>zeus</data-source-name>
</configuration>
</component>
<component>
<role>org.unidal.dal.jdbc.mapping.TableProvider</role>
<role-hint>operation-log</role-hint>
<implementation>org.unidal.dal.jdbc.mapping.SimpleTableProvider</implementation>
<configuration>
<physical-table-name>operation_log</physical-table-name>
<data-source-name>zeus</data-source-name>
</configuration>
</component>
<component>
<role>org.unidal.dal.jdbc.mapping.TableProvider</role>
<role-hint>report</role-hint>
@ -485,6 +494,15 @@
</requirement>
</requirements>
</component>
<component>
<role>com.ctrip.zeus.dal.core.OperationLogDao</role>
<implementation>com.ctrip.zeus.dal.core.OperationLogDao</implementation>
<requirements>
<requirement>
<role>org.unidal.dal.jdbc.QueryEngine</role>
</requirement>
</requirements>
</component>
<component>
<role>com.ctrip.zeus.dal.core.ReportDao</role>
<implementation>com.ctrip.zeus.dal.core.ReportDao</implementation>

View file

@ -24,4 +24,7 @@
<model package="com.ctrip.zeus.report" name="report">
<sample-model>src/test/resources/com/ctrip/zeus/model/report.xml</sample-model>
</model>
<model package="com.ctrip.zeus.operationlog" name="operationlog">
<sample-model>src/test/resources/com/ctrip/zeus/model/operationlog.xml</sample-model>
</model>
</wizard>

View file

@ -96,6 +96,10 @@
<constructor-arg type="java.lang.Class" value="com.ctrip.zeus.dal.core.NginxServerDao"/>
</bean>
<bean id="operationLogDao" factory-bean="daoFactory" factory-method="getDao">
<constructor-arg type="java.lang.Class" value="com.ctrip.zeus.dal.core.OperationLogDao"/>
</bean>
<bean id="reportDao" factory-bean="daoFactory" factory-method="getDao">
<constructor-arg type="java.lang.Class" value="com.ctrip.zeus.dal.core.ReportDao"/>
</bean>

View file

@ -0,0 +1,18 @@
<operationlog>
<operation-log-data-list>
<total>1</total>
<operation-log-data>
<type>string</type>
<target-id>string</target-id>
<operation>string</operation>
<user-name>string</user-name>
<data>string</data>
<client-ip>string</client-ip>
<success>true</success>
<err-msg>string</err-msg>
<date-time>2013-05-20 13:34:00</date-time>
</operation-log-data>
<operation-log-data/>
</operation-log-data-list>
</operationlog>