Log Viewer(MVC)

使用MVC开发的日志在线管理表单,支持内容分页、按目录读取文件、配置操作权限等;

 

效果图:

 

BLL Code:

 

复制代码
View Code
public class DiskLog : ILog
    {
        
public int CalcTotalPage(long totalCount, int pageSize)
        {
            
if (totalCount % pageSize == 0)
                
return (int)(totalCount / pageSize);
            
else
                
return (int)(totalCount / pageSize + 1);
        }

        
/// <summary>
        
/// Paging Read File
        
/// </summary>
        
/// <param name="fileName"></param>
        
/// <param name="pageIndex"></param>
        
/// <param name="pageSize"></param>
        
/// <returns></returns>
        public string ReadFile(string fileName, int pageIndex, int pageSize)
        {
            FileStream fs 
= null;
            StreamReader sr 
= null;
            Pagination
<string> page = new Pagination<string>();
            
try
            {
                fs 
= new FileStream(fileName, FileMode.Open, FileAccess.Read);
                sr 
= new StreamReader(fs);
                
int arrSize = pageSize;
                
long totalByte = fs.Length;
                
if (pageSize > totalByte)
                    arrSize 
= (int)totalByte;
                
else if ((pageIndex * pageSize) > totalByte)
                    arrSize 
= 0;
                
else if ((pageIndex * pageSize) < totalByte && CalcTotalPage(totalByte, pageSize) == pageIndex)
                    arrSize 
= (int)(totalByte - (pageIndex * pageSize));

                
if (arrSize > 0)
                {
                    
char[] fileContent = new char[arrSize];
                    
int offset = (pageSize > totalByte) ? 0 : pageIndex * pageSize;
                    sr.BaseStream.Seek(offset, SeekOrigin.Begin);
                    sr.ReadBlock(fileContent, 
0, arrSize);
                    page.CurrentPageIndex 
= pageIndex;
                    page.PageCount 
= CalcTotalPage(totalByte, pageSize);
                    page.TotalCount 
= totalByte;
                    page.Data 
= new string(fileContent);
                    Array.Clear(fileContent, 
0, fileContent.Length);

                    page.PageSize 
= pageSize;
                    page.CurrentPageIndex 
= pageIndex;
                }
            }
            
catch (Exception ex)
            {

            }
            
finally
            {
                
if (sr != null)
                {
                    sr.Close();
                    sr.Dispose();
                }
                
if (fs != null)
                {
                    fs.Close();
                    fs.Dispose();
                }
            }
            
return page.ToJson();
        }


        
/// <summary>
        
///Get File List
        
/// </summary>
        
/// <param name="path"></param>
        
/// <returns></returns>
        public string[] GetFileList(string dirPath)
        {
            
if (Directory.Exists(dirPath))
            {
                DirectoryInfo dir 
= new DirectoryInfo(dirPath);
                FileInfo[] files 
= dir.GetFiles("*.*");
                
string[] fileNames = new string[files.Length];
                
int i = 0;
                
foreach (FileInfo fileInfo in files)
                {
                    fileNames[i] 
= fileInfo.Name;
                    i
++;
                }
                
return fileNames;
            }
            
else
            {
                
return null;
            }
        }
        
/// <summary>
        
/// Read  File
        
/// </summary>
        
/// <param name="filename"></param>
        
/// <returns></returns>
        public string ReadFile(string filename)
        {
            StreamReader sr 
= null;
            
try
            {
                sr 
= File.OpenText(filename);
                
string data = "{\"Data\":\"" + Microsoft.JScript.GlobalObject.escape(sr.ReadToEnd()) + "\"}";
                
return data;
            }
            
catch (Exception ex)
            {
                
return ex.Message;
            }
            
finally
            {
                
if (sr != null)
                {
                    sr.Close();
                    sr.Dispose();
                }
            }

        }
        
/// <summary>
        
/// Delete File
        
/// </summary>
        
/// <param name="filepath"></param>
        public bool DeleteFile(string filepath)
        {
            
try
            {
                File.Delete(filepath);
                
return true;
            }
            
catch
            {
                
return false;
            }
        }

        
/// <summary>
        
/// Save File
        
/// </summary>
        
/// <param name="filename"></param>
        
/// <param name="content"></param>
        public bool SaveFile(string filename, string content)
        {
            
try
            {
                System.IO.File.WriteAllText(filename, content);
                
return true;
            }
            
catch
            {
                
return false;
            }
        }
        
/// <summary>
        
/// Clear File
        
/// </summary>
        
/// <param name="filename"></param>
        public bool ClearFile(string filename)
        {
            
try
            {
                File.WriteAllText(filename, 
"");
                
return true;
            }
            
catch
            {
                
return false;
            }
        }

    }
复制代码

 

Controller Code:

 

复制代码
View Code
public class LogViewerController : Controller
    {
        [HttpGet]
        
public ActionResult Index()
        {
            
return View();
        }

        
/// <summary>
        
/// Get File Tree Data
        
/// </summary>
        
/// <returns></returns>
        public string GetTreeData()
        {
            StringBuilder treeJson 
= new StringBuilder();
            treeJson.Append(
"[");
            
int index = 0;
            var lstGroup 
= GetLogGroups();
            treeJson.Append(
"{\"id\":" + index + ",\"text\":\"Root\",\"iconCls\":\"icon-save\",\"state\":\"open\"");
            
if (lstGroup.Count > 0)
                treeJson.Append(
",\"children\":[");
            index 
= index + 1;
            
foreach (var group in lstGroup)
            {
                treeJson.Append(
"{\"id\":" + index + ",\"text\":\"" + group.GroupName + "\",\"iconCls\":\"icon-save\",\"state\":\"open\"");

                index
++;
                
if (group.IsAllFile == false && group.LogItemCollection.Count > 0)
                {
                    treeJson.Append(
",\"children\":[");
                    
// Get All Item
                    foreach (var item in group.LogItemCollection)
                    {
                        treeJson.Append(
"{\"id\":" + index + ",\"text\":\"" + item.Name + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(item.FullName) + "\",\"CanPaging\":\"" + item.CanPaging + "\",\"CanModify\":\"" + item.CanModify + "\",\"CanClear\":\"" + item.CanClear + "\",\"CanDelete\":\"" + item.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");

                        index
++;
                    }
                    treeJson.Remove(treeJson.Length 
- 11);
                    treeJson.Append(
"]");
                }
                
else
                {
                    Log.DiskLog log 
= new Log.DiskLog();
                    
string[] arrFileName = log.GetFileList(group.DirectoryPath);
                    
if (arrFileName != null && arrFileName.Length > 0)
                    {
                        treeJson.Append(
",\"children\":[");
                        
foreach (var fileName in arrFileName)
                        {
                            
string fullName = group.DirectoryPath + "\\" + fileName;
                            treeJson.Append(
"{\"id\":" + index + ",\"text\":\"" + fileName + "\",\"attributes\":[{\"fullName\":\"" + HttpUtility.JavaScriptStringEncode(fullName) + "\",\"CanPaging\":\"" + group.CanPaging + "\",\"CanModify\":\"" + group.CanModify + "\",\"CanClear\":\"" + group.CanClear + "\",\"CanDelete\":\"" + group.CanDelete + "\"}],\"iconCls\":\"icon-save\",\"state\":\"open\"},");
                            index
++;
                        }
                        treeJson.Remove(treeJson.Length 
- 11);
                        treeJson.Append(
"]");
                    }
                }
                treeJson.Append(
"},");
            }
            
if (lstGroup.Count > 0)
            {
                treeJson.Remove(treeJson.Length 
- 11);
                treeJson.Append(
"]}");
            }
            treeJson.Append(
"]");
            
return treeJson.ToString();
        }

        
/// <summary>
        
/// Update file content
        
/// </summary>
        
/// <param name="filename">target file path</param>
        
/// <param name="content"></param>
        
/// <returns></returns>
        [ValidateInput(false)]
        
public string Modify(string filename, string content)
        {
            Log.DiskLog log 
= new Log.DiskLog();
            
// save file
            bool isSuccee = log.SaveFile(filename, content);
            
string message = isSuccee ? ("Modify Succeed!") : ("Modify error!");
            
return message;
        }

        
/// <summary>
        
/// Clear file content
        
/// </summary>
        
/// <param name="filename">target file path</param>
        
/// <returns></returns>
        public string Clear(string filename)
        {
            Log.DiskLog log 
= new Log.DiskLog();
            
// clear file
            bool isSuccee = log.ClearFile(filename);
            
string message = isSuccee ? ("Clear succeed!") : ("Clear error!");

            
return message;
        }

        
/// <summary>
        
/// Delete file 
        
/// </summary>
        
/// <param name="filename">target file path</param>
        
/// <returns></returns>
        public string Delete(string filename)
        {
            Log.DiskLog log 
= new Log.DiskLog();
            
// delete file
            bool isSuccee = log.DeleteFile(filename);
            
string message = isSuccee ? ("Delete succeed!") : ("Delete error!");

            
return message;
        }

        
/// <summary>
        
/// Get file content by file path
        
/// </summary>
        
/// <param name="filePath">target file path</param>
        
/// <returns>file content</returns>
        public string ReadFile(string filename, int pageIndex, int pageSize, bool canPaging)
        {
            Log.DiskLog log 
= new Log.DiskLog();
            
if (canPaging)
                
return log.ReadFile(filename, pageIndex, pageSize);
            
else
                
return log.ReadFile(filename);
        }

        
public bool IsRelativePath(string path)
        {
            
return path.Contains("~/");
        }

        
public bool GetNodeBoolAttr(XmlNode node, string attrName)
        {
            
string sIsTrue = (node.Attributes[attrName] != null? node.Attributes[attrName].Value : "false";
            
bool isTrue = false;
            
bool.TryParse(sIsTrue, out isTrue);
            
return isTrue;
        }

        
public string GetNodeStringAttr(XmlNode node, string attrName)
        {
            
string sValue = (node.Attributes[attrName] != null? node.Attributes[attrName].Value : string.Empty;

            
return sValue;
        }

        
/// <summary>
        
/// Get Log configuration return log group
        
/// </summary>
        
/// <returns></returns>
        private List<LogGroup> GetLogGroups()
        {
            List
<LogGroup> lstLogGroup = new List<LogGroup>();
            
string logconfigpath = System.Configuration.ConfigurationManager.AppSettings["LogConfig"];// Server.MapPath("~/") + "Log.config"; //
            
// check path 
            if (IsRelativePath(logconfigpath))
                logconfigpath 
= Server.MapPath(logconfigpath);
            XmlDocument doc 
= new XmlDocument();
            
try
            {
                doc.Load(logconfigpath);

                var root 
= doc.SelectSingleNode("//root");
                
foreach (XmlNode groupNode in root.ChildNodes)
                {
                    
if (groupNode.Name == "loggroup")
                    {
                        
string groupName = GetNodeStringAttr(groupNode, "name");
                        
string dirPath = GetNodeStringAttr(groupNode, "dirpath");
                        
if (IsRelativePath(dirPath))
                            dirPath 
= Server.MapPath(dirPath);
                        
bool isAllFile = GetNodeBoolAttr(groupNode, "isallfile");
                        
bool groupCanPaging = GetNodeBoolAttr(groupNode, "CanPaging");
                        
bool groupCanModify = GetNodeBoolAttr(groupNode, "CanModify");
                        
bool groupCanClear = GetNodeBoolAttr(groupNode, "CanClear");
                        
bool groupCanDelete = GetNodeBoolAttr(groupNode, "CanDelete");
                        List
<LogItem> lstLogItem = new List<LogItem>();
                        
foreach (XmlNode itemNode in groupNode)
                        {
                            
if (itemNode.Name == "logitem")
                            {
                                LogItem logItem 
= new LogItem();
                                
string itemName = GetNodeStringAttr(itemNode, "name");
                                
string fullName = GetNodeStringAttr(itemNode, "fullname");
                                
bool canPaging = GetNodeBoolAttr(itemNode, "CanPaging");
                                
bool canModify = GetNodeBoolAttr(itemNode, "CanModify");
                                
bool canClear = GetNodeBoolAttr(itemNode, "CanClear");
                                
bool canDelete = GetNodeBoolAttr(itemNode, "CanDelete");
                                
if (IsRelativePath(fullName))
                                    fullName 
= Server.MapPath(fullName);
                                logItem.Name 
= itemName;
                                logItem.FullName 
= fullName;
                                logItem.CanPaging 
= canPaging;
                                logItem.CanModify 
= canModify;
                                logItem.CanClear 
= canClear;
                                logItem.CanDelete 
= canDelete;
                                
// Add to lstLogItem
                                lstLogItem.Add(logItem);
                            }
                        }
                        LogGroup logGroup 
= new LogGroup();
                        logGroup.GroupName 
= groupName;
                        logGroup.DirectoryPath 
= dirPath;
                        logGroup.IsAllFile 
= isAllFile;
                        logGroup.LogItemCollection 
= lstLogItem;
                        logGroup.CanPaging 
= groupCanPaging;
                        logGroup.CanModify 
= groupCanModify;
                        logGroup.CanClear 
= groupCanClear;
                        logGroup.CanDelete 
= groupCanDelete;
                        
// Add to lstLogGroup
                        lstLogGroup.Add(logGroup);
                    }
                }
            }
            
catch (Exception ex)
            { }
            
return lstLogGroup;
        }

    }
复制代码

 

UI Code:

 

复制代码
View Code
@{
    Layout = "";
}
<!DOCTYPE html>
<html>
<head>
    
<title>Log Index</title>
    
<link href="@Url.Content("~/Content/reset.css")" rel="stylesheet" type="text/css" />
    
<link href="@Url.Content("~/Content/Admin.css")" rel="stylesheet" type="text/css" />
    
<link href="@Url.Content("~/Content/easyui_themes/gray/easyui.css")" rel="stylesheet" type="text/css" />
    
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
    
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
    
<script src="@Url.Content("~/Scripts/jquery.easyui.min.js")" type="text/javascript"></script>
    
<script src="@Url.Content("~/Scripts/Log.js")" type="text/javascript"></script>
    
<script type="text/javascript">
        
var sureDelete = 'Sure you want to delete?';
        
var confirm = 'Confirm';
        
var prompt = 'Prompt';
        
var selectFileError = 'Must select a item';
        
var selectMustFile = 'Select type must is file';
    
</script>
</head>
<body>
    @using (Ajax.BeginForm(null))
    {
        @Html.ValidationSummary(true)
    
        
<table style="width: 98%; height: 98%;">
            
<tr>
                
<td>
                    
<id="lnkDelete" href="javascript:DeleteFile();" class="easyui-linkbutton">Delete</a>
                    
<id="lnkRefreshTree" href="javascript:TreeInit();" class="easyui-linkbutton">Refresh</a>
                
</td>
                
<td>
                
<strong>FileName:</strong><label id="lblFileName"></label>
                
</td>
                
<td style="text-align: right;">
                    
                   
<id="lnkModify" href="javascript:Modify();" class="easyui-linkbutton">Modify</a>
                            
<id="lnkClear" href="javascript:Clear();" class="easyui-linkbutton">Clear</a>
                            
<id="lnkRefreshFile" href="javascript:OpenFile();" class="easyui-linkbutton">Refresh</a>
                    
                
</td>
            
</tr>
            
<tr>
                
<td style="width: 20%; height: 100%; vertical-align: top">
                    
<ul id="treeFile">
                    
</ul>
                
</td>
                
<td colspan="2" style="width: 80%; height: 100%; vertical-align: top">
                    @Html.TextArea("txtContent", new { style = "height:500px;width:100%;" })
                    
<div id="divPaging" style="text-align: right">
                        Show Page Size(byte)
                        
<select id="sltPageSize">
                            
<option value="1024">1024</option>
                            
<option value="2048">2048</option>
                            
<option value="4069">4069</option>
                        
</select>
                        Total Page Size:
<label id="lblMaxPageCount">0</label>
                        
<id="lnkPre" href="javascript:" class="easyui-linkbutton">Previous</a><a
                            
id="lnkNext" href="javascript:" class="easyui-linkbutton">Next</a>
                        
<input id="txtPageIndex" type="text" style="width: 40px; height: 12px" /><id="lnkGo"
                            href
="javascript:" class="easyui-linkbutton">Go</a>
                    
</div>
                
</td>
            
</tr>
        
</table>
@*
<div id="loading" style="position: fixed !important; position: absolute; top: 0;display:none;
        left: 0; height: 100%; width: 100%; z-index: 999; background: #000 url(http://interjc.googlecode.com/svn/trunk/waterfall/img/load.gif) no-repeat center center;
        opacity: 0.6; filter: alpha(opacity=60); font-size: 14px; line-height: 20px;"
>
        
<id="loading-one" style="color: #fff; position: absolute; top: 50%; left: 50%;
            margin: 20px 0 0 -50px; padding: 3px 10px;"
 onclick="javascript:Loaded()">
            页面载入中..
        
</p>
    
</div>   *@
    
    }
</body>
</html>
复制代码

 

JS Code:

 

复制代码
View Code
var fullName = "";
var currentPageIndex 
= 1;
var pageCount 
= 1;
var pageSize 
= 1024;
var canPaging 
= false;
function CheckPageIndex() {
    var pageIndex 
= parseInt($("#txtPageIndex").val());
    $(
"#lnkGo").attr('disabled', (isNaN(pageIndex) || pageIndex > pageCount));
}
$(document).ready(function () {
    
// init file tree
    TreeInit();
    $(
"#lnkPre").attr('disabled', (currentPageIndex == 1));
    $(
"#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
    $(
"#sltPageSize").change(function () {
        pageSize 
= $("#sltPageSize option:selected").val();
        OpenFile();
    });
    
if ($.browser.msie) {
        $(
"#txtPageIndex").bind("propertychange", CheckPageIndex);
    }
    
else {
        $(
"#txtPageIndex").bind("blur", CheckPageIndex)
    }

    $(
"#txtPageIndex").val(currentPageIndex);

    $(
"#lnkPre").click(function () {
        currentPageIndex 
= currentPageIndex - 1;
        OpenFile();
    });
    $(
"#lnkNext").click(function () {
        currentPageIndex 
= currentPageIndex + 1;
        OpenFile();
    });
    $(
"#lnkGo").click(function () {
        currentPageIndex 
= parseInt($("#txtPageIndex").val());
        OpenFile();
    });
    $(
"#divPaging").hide();
});

function TreeInit() {
//    Loading('@this.T("Loading data...")');
    $('#treeFile').tree({
        url: 
'/LogViewer/GetTreeData',
        onClick: function (node) {
            
if (node.attributes != undefined) {
                fullName 
= decodeURI(node.attributes[0].fullName);
                $(
"#lblFileName").text(fullName);
                canPaging 
= node.attributes[0].CanPaging == "True";
                var canModify 
= node.attributes[0].CanModify;
                var canClear 
= node.attributes[0].CanClear;
                var canDelete 
= node.attributes[0].CanDelete;
                $(
"#lnkDelete").attr("disabled", canDelete == "False");
                $(
"#lnkClear").attr("disabled", canClear == "False");
                $(
"#lnkModify").attr("disabled", canModify == "False");
                
if (canPaging)
                    $(
"#divPaging").show();
                
else
                    $(
"#divPaging").hide();
                currentPageIndex 
= 1;
                OpenFile();
            } 
else
                $(
"#txtContent").val("");
        },
        onLoadSuccess: function (msg) {
            
//            Loaded('@this.T("Complete!")');
        }
    });
    
// clear txtContext.Text
    $("#txtContent").val("");
}
function DataCheck() {
    var node 
= $('#treeFile').tree('getSelected');
    
if (node == null) {
        $.messager.alert(prompt, selectFileError);
        
return false;
    }
    
if (node.attributes == undefined) {
        $.messager.alert(prompt, selectMustFile);
        
return false;
    }
    
return true;
}
function Clear() {
    
if (DataCheck()) {
        $.messager.confirm(confirm, sureDelete, function (r) {
            
if (r) {
                $.ajax(
                {
                    type: 
"Post",
                    url: 
"/LogViewer/Clear",
                    data: 
"filename=" + fullName,
                    success: function (returndata) {
                        
// refresh txtContext.Text
                        currentPageIndex = 1;
                        OpenFile();

                        $.messager.alert(prompt, returndata);
                    }
                });
            }
        });
    }
}

function Modify() {
    
if (DataCheck()) {
        var filename 
= fullName;
        var content 
= $("#txtContent").val();
        $.ajax(
                {
                    type: 
"Post",
                    url: 
"/LogViewer/Modify",
                    data: 
"filename=" + filename + "&content=" + content,
                    success: function (returndata) {
                        $.messager.alert(prompt, returndata);
                    },
                    error: function (xhr, status, errMsg) {
                        
//                        alert(errMsg.msg);
                    }
                });
    }
}
function OpenFile() {
    
if (DataCheck()) {
//        Loading('@this.T("Loading data...")');
        $.getJSON(
                
"/LogViewer/ReadFile?date=" + new Date(),
                { filename: fullName, pageIndex: currentPageIndex 
- 1, pageSize: pageSize, canPaging: canPaging },
                function (data) {
                    
if (canPaging) {
                        var content 
= unescape(data[0].Data);
                        pageCount 
= data[0].PageCount;
                        var totalCount 
= data[0].TotalCount;
                        $(
"#txtContent").val(content);
                        $(
"#lblMaxPageCount").text(pageCount);
                        $(
"#txtPageIndex").val(currentPageIndex);
                        $(
"#lnkPre").attr('disabled', (currentPageIndex == 1));
                        $(
"#lnkNext").attr('disabled', (currentPageIndex >= pageCount));
                    } 
else
                    {
                        var content 
= unescape(data.Data);
                        $(
"#txtContent").val(content);
                     }
                    
//                    Loaded('@this.T("Complete!")');
                });
    }
}
function DeleteFile() {
    
if (DataCheck()) {
        $.messager.confirm(confirm, sureDelete, function (r) {
            
if (r) {
                $.ajax(
                        {
                            type: 
"Post",
                            url: 
"/LogViewer/Delete",
                            data: 
"filename=" + fullName,
                            success: function (returndata) {
                                
// refresh file tree
                                TreeInit();
                                $.messager.alert(prompt, returndata);
                            }
                        });
            }
        });
    }
}
复制代码

 Log.config

 

复制代码
<?xml version="1.0" encoding="utf-8" ?>
<root>
  
<loggroup name="log" dirpath="F:\Billy\src\CTBlazer\Bin\Log" isallfile="true" CanPaging="true" CanModify="false" CanClear="true" CanDelete="true">
  
</loggroup>
  
<loggroup name="config" dirpath="">
    
<logitem name="web.config" fullname="~/web.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
    
<logitem name="Log.config" fullname="~/Log.config" CanPaging="false" CanModify="true" CanClear="false" CanDelete="false"></logitem>
  
</loggroup>
</root>
复制代码

 

 

posted on   木子清  阅读(688)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了

导航

< 2011年5月 >
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4
5 6 7 8 9 10 11

统计

我的网站:道道工作室
点击右上角即可分享
微信分享提示