abp 中虽然已经有日志模块,但是没有UI界面,而一个日志界面对开发的应用程序来说很重要,因此,经过一番摸索,终于做出了自己的日志模块,列出关键代码,给有需要的朋友参考。
1、首先,在Application.Contracts项目中新增加一个类AuditLogDto.cs 和GetAuditLogInput.cs:
代码块
public class AuditLogDto : EntityDto<Guid>
{
public virtual string ApplicationName { get; set; }
public virtual Guid? UserId { get; protected set; }
public virtual string UserName { get; protected set; }
public virtual Guid? TenantId { get; protected set; }
public virtual string TenantName { get; protected set; }
public virtual Guid? ImpersonatorUserId { get; protected set; }
public virtual Guid? ImpersonatorTenantId { get; protected set; }
public virtual DateTime ExecutionTime { get; protected set; }
public virtual int ExecutionDuration { get; protected set; }
public virtual string ClientIpAddress { get; protected set; }
public virtual string ClientName { get; protected set; }
public virtual string ClientId { get; set; }
public virtual string CorrelationId { get; set; }
public virtual string BrowserInfo { get; protected set; }
public virtual string HttpMethod { get; protected set; }
public virtual string Url { get; protected set; }
public virtual string Exceptions { get; protected set; }
public virtual string Comments { get; protected set; }
public virtual int? HttpStatusCode { get; set; }
public virtual ICollection<EntityChange> EntityChanges { get; protected set; }
public virtual ICollection<AuditLogAction> Actions { get; protected set; }
}
public class GetAuditLogInput : PagedAndSortedResultRequestDto
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string UserName { get; set; }
public string ServiceName { get; set; }
public string MethodName { get; set; }
public string BrowserInfo { get; set; }
public string HttpMethod { get; set; }
public string Url { get; set; }
public string UseName { get; set; }
public string ApplicationName { get; set; }
public string CorrelationId { get; set; }
public int? MaxExecutinDuration { get; set; }
public int? MinExecutionDuration { get; set; }
public System.Net.HttpStatusCode? httpStutusCode { get; set; }
public bool IncludeDetails { get; set; }
public bool? HasException { get; set; }
}
2、增加IAuditLogAppService.cs类
public interface IAuditLogAppService : IApplicationService
{
Task<PagedResultDto<AuditLogDto>> GetListAsync(GetAuditLogInput input);
}
3、在Application项目在增加AuditLogAppService.cs类:
public class AuditLogAppService : XXAppService, IAuditLogAppService
{
private readonly IAuditLogRepository _auditLogRepository;
public AuditLogAppService(IAuditLogRepository auditLogRepository)
{
_auditLogRepository = auditLogRepository;
}
public async Task<PagedResultDto<AuditLogDto>> GetListAsync(GetAuditLogInput input)
{
input.Sorting = "ExecutionTime Desc";
input.IncludeDetails = true;
var count = await _auditLogRepository.GetCountAsync(
input.StartDate, input.EndDate, input.HttpMethod,
input.Url, input.UseName, input.ApplicationName, input.CorrelationId, input.MaxExecutinDuration,
input.MinExecutionDuration, input.HasException, input.httpStutusCode).ConfigureAwait(false);
var list = await _auditLogRepository.GetListAsync(input.Sorting,
input.MaxResultCount, input.SkipCount, input.StartDate, input.EndDate, input.HttpMethod,
input.Url, input.UseName, input.ApplicationName, input.CorrelationId, input.MaxExecutinDuration, input.MinExecutionDuration,
input.HasException, input.httpStutusCode, input.IncludeDetails
).ConfigureAwait(false);
return new PagedResultDto<AuditLogDto>(
count,
ObjectMapper.Map<List<AuditLog>, List<AuditLogDto>>(list)
);
}
4、XXApplicationAutoMapperProfile.cs 类中增加 AutoMap类映射关系:
public class AuditManagementApplicationAutoMapperProfile : Profile
{
public AuditManagementApplicationAutoMapperProfile()
{
CreateMap<AuditLog, AuditLogDto>();
}
}
5、web 项目中Pages目录下增加AuditLogs目录,在AuditLogs目录下增加index.cshtml文件:
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<h2>@L["AbpAuditLogs"]</h2>
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<form id="AuditLogFilterForm">
<abp-row>
<abp-column size-md="_3">
<div class="form-group">
<label for="StartEndRange" class="control-label">@L["DateRange"]</label>
<input id="StartEndRange" type="text" class="form-control date-range-picker" />
</div>
</abp-column>
<abp-column size-md="_3">
<abp-input asp-for="@Model.Input.UserName" label="用户" />
</abp-column>
<abp-column size-md="_3">
<abp-select asp-for="@Model.Input.HttpStutusCode" asp-items="@Model.HttpStutusCodes" label="Http状态码" />
</abp-column>
<abp-column size-md="_3">
<abp-select asp-for="@Model.Input.HttpMethod" asp-items="@Model.HttpMethods" label="http方法"/>
</abp-column>
</abp-row>
<abp-row>
<abp-column size-md="_3">
<abp-select asp-for="@Model.Input.HasException" asp-items="@Model.HasExceptions" label="有错误" />
</abp-column>
<abp-column size-md="_3">
<button id="RefreshAuditLogsButton" class="btn btn-primary"><i class="fa fa-sync"></i> @L["Refresh"]</button>
</abp-column>
</abp-row>
</form>
<abp-table striped-rows="true" id="AbpAuditLogssTable">
<thead>
<tr>
<th width="40">@L["Http"]</th>
<th width="40">@L["Method"]</th>
<th>@L["UserName"]</th>
<th>@L["ExecutionDuration"]</th>
<th>@L["ClientIpAddress"]</th>
<th>@L["Url"]</th>
<th>@L["ExecutionTime"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
6、增加index.js代码:
$(function () {
var l = abp.localization.getResource('AuditManagement');
var _auditLogService = xxxnamespace.auditLog;
var _$auditLogFilterForm = $('#AuditLogFilterForm');
var _$auditLogsTable = $('#AbpAuditLogssTable');
var _selectedDateRangeAuditLog = {
startDate: moment().startOf('day'),
endDate: moment().endOf('day')
};
var createDateRangePickerOptions = function (extraOptions) {
extraOptions = extraOptions ||
{
allowFutureDate: false
};
var options = {
locale: {
format: 'L',
applyLabel: l('Apply'),
cancelLabel: l('Cancel'),
customRangeLabel: l('CustomRange')
},
min: moment('2015-05-01'),
minDate: moment('2015-05-01'),
opens: 'left',
ranges: {}
};
if (!extraOptions.allowFutureDate) {
options.max = moment();
options.maxDate = moment();
}
options.ranges[l('Today')] = [moment().startOf('day'), moment().endOf('day')];
options.ranges[l('Yesterday')] = [moment().subtract(1, 'days').startOf('day'), moment().subtract(1, 'days').endOf('day')];
options.ranges[l('Last7Days')] = [moment().subtract(6, 'days').startOf('day'), moment().endOf('day')];
options.ranges[l('Last30Days')] = [moment().subtract(29, 'days').startOf('day'), moment().endOf('day')];
options.ranges[l('ThisMonth')] = [moment().startOf('month'), moment().endOf('month')];
options.ranges[l('LastMonth')] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
return options;
};
_$auditLogFilterForm.find('input.date-range-picker').daterangepicker(
$.extend(true, createDateRangePickerOptions(), _selectedDateRangeAuditLog),
function (start, end) {
_selectedDateRangeAuditLog.startDate = start.format('YYYY-MM-DDT00:00:00Z');
_selectedDateRangeAuditLog.endDate = end.format('YYYY-MM-DDT23:59:59.999Z');
getAuditLogs();
});
var dataTable = _$auditLogsTable.DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(_auditLogService.getList,
function () { return createAuditLogRequestParams() }),
columnDefs: [
{
data: "httpStatusCode"
},
{
data: "httpMethod"
},
{ data: "userName" },
{ data: "executionDuration" },
{ data: "clientIpAddress" },
{ data: "url" },
{
data: "executionTime",
render: function (executionTime) {
return moment(executionTime).format('YYYY-MM-DD HH:mm:ss');
}
}
]
}));
function createAuditLogRequestParams() {
var prms = {};
_$auditLogFilterForm.serializeArray().map(function (x) {
prms[abp.utils.toCamelCase(x.name.substring(6))] = x.value;
});
return $.extend(prms, _selectedDateRangeAuditLog);
}
function getAuditLogs() {
dataTable.ajax.reload();
}
$('#RefreshAuditLogsButton').click(function (e) {
e.preventDefault();
getAuditLogs();
});
});
7、在xxMenuContributor.cs中添加菜单:
context.Menu.Items.Add(new ApplicationMenuItem("Stock.Audit", l["Menu:Audit"], "/Audits"));
基本的代码就是这些,当然,如果要真正做成一个实用的日志功能,最好是把它做成一个模块,然后添加到你的新项目中。还要有查询功能等等。
上面的图片是我最终做出来的日志界面,还有待完善。