精华内容
下载资源
问答
  • 日期控件 对于web时间很好的格式化输出
  • Log4J输出日志会影响WEB应用响应时间

    千次阅读 2010-09-20 17:32:00
    由于客户对系统性能要求很高,所有请求的相应时间必须在1秒内,所以我们在做开发的时候,特别注意页面的相应时间

        由于客户对项目的页面响应时间要求很高,所有请求的响应时间必须在1秒内,因此我们在做开发的时候,特别注意效率问题。今天我在自己的机器上对系统做优化时,发现有个页面怎么调整都无法达到要求,即使把访问数据库取数据的方法都屏蔽了,页面的响应时间依然为2秒多。对所有可能有效率问题的地方使用per4j,监视方法的执行时间。结果非常出乎意料,有一个使用log4j输出日志的地方,居然耗时600ms。狂晕,立刻修改log4j的配置,将DEBUG模式改成Error模式,再次测试,速度有了质的飞跃,响应时间上升到100ms左右。继续修改log4j的配置文件,发现将日志输出到文件中,速度并不慢,如果输出到控制台,速度下降很多。最后,我将Log4j的配置改成DEBUG模式,只把日志输出到文件。

     

    测试系统环境:

    JDK1.6.0.20

    Log4j1.2.8

     

    参考资料:

    1,Log4j,http://logging.apache.org/log4j/1.2/index.html

     

    展开全文
  • WebApi接口 - 响应输出xml和json

    千次阅读 2017-02-25 08:09:04
    WebApi接口 - 响应输出xml和json格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况;希望大家喜欢,也希望...

    WebApi接口 - 响应输出xml和json


    格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况;希望大家喜欢,也希望各位多多扫码支持和点赞谢谢:

    . 自定义一个Action,响应输出集合数据

    . api返回json数据的两种方式

    . json时间格式处理方式

    . 让api接口支持返回json和xml数据

    下面一步一个脚印的来分享:

    . 自定义一个Action,响应输出集合数据

    首先,我们新建一个webapi项目,新建好以后我们能够找到 Controllers/ValuesController.cs 文件,查看里面有自动生成的一些代码,我们先不管;然后我们创建一个学生 MoStudent 类,属性代码如:

     1 public class MoStudent
     2     {
     3         public DateTime Birthday { get; set; }
     4 
     5         public int Id { get; set; }
     6 
     7         public string Name { get; set; }
     8 
     9         public bool Sex { get; set; }
    11     }

    然后我们在 ValuesController 中初始化一些公共的数据,代码如:

    1  public List<MoStudent> students = new List<MoStudent>() { 
    2         
    3              new MoStudent{ Id =1 , Name ="小1", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")},
    4              new MoStudent{ Id =2 , Name ="小2", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")},
    5              new MoStudent{ Id =3 , Name ="小3", Sex = false, Birthday= Convert.ToDateTime("1991-05-31")},
    6              new MoStudent{ Id =4 , Name ="小4", Sex = true, Birthday= Convert.ToDateTime("1991-05-31")}
    7         };

    再来,我们新创建一个 GetAllStudents01() 方法,并输出学生集合数据,代码如:

    1  public List<MoStudent> GetAllStudents01()
    2         {
    3             return students;
    4         }

    这个时候我们生成一下项目,然后在浏览器访问下地址为: http://localhost:1001/api/values ,此时会提示一个错误信息:

    这个错误信息是该地址同时匹配上了两个api的Action,分别为 Get()和GetAllStudents01() 两个方法,这种错误我们应该怎么处理呢;一种可以删除其中一个方法;二种方式是在默认路由设置下Action,然后通过具体的Controller/Action地址来访问;三种是通过Route修改下对应的访问路由(这种方法前面一篇文章已经有说明);这里我们就使用第二种,先来修改下 WebApiConfig.cs 文件中默认路由的配置,修改后的配置如:

    1 config.Routes.MapHttpRoute(
    2                 name: "DefaultApi",
    3                 routeTemplate: "api/{controller}/{action}/{id}",
    4                 defaults: new { id = RouteParameter.Optional }
    5             );

    生成后,我们在浏览器中这样访问: http://localhost:1001/api/values/GetAllStudents01 ,GetAllStudents01是对应要访问的Action名称,不出意外我们能在浏览器中看到如下结果:

    webapi能正常返回数据了,但是地址感觉好长的样子,不利于我们测试,那么下么我们使用上一篇文章用到的标记RoutePrefixRoute来变动下路由,增加的代码如:

    然后我们测试访问下该地址: http://localhost:1001/s/all01 能正常返回如上面的截图数据;

     

    . api返回json数据的两种方式

     首先,我们回顾下看下上面节点例子的截图,接口响应输出的是xml格式的数据,这里默认采用的是webapi自带的xml格式化方式,把 Student 属性全部展示了出来,我们真实开发接口的时候,通常会有些对象的属性不会展示,下面我们通过增加 DataContract 和 DataMember 来设置把不需要暴露的属性“隐藏掉”,我们先来看先增加了这两个标记后的Student实体:

     1 [DataContract]
     2     public class MoStudent
     3     {
     4         [DataMember]
     5         public DateTime Birthday { get; set; }
     6 
     7         [DataMember]
     8         public int Id { get; set; }
     9 
    10         [DataMember]
    11         public string Name { get; set; }
    12 
    13         [DataMember]
    14         public bool Sex { get; set; }
    15 
    16     }

    然后咋们运行下程序,在页面看到的结果信息和之前的结果一模一样:

    下面把 Birthday 属性上面的 DataMember 去掉,然后再来运行查看结果:

    可以看到输出的结果中已经没有了这个 Birthday ,这里能看出的结果是如果未标记 DataMember ,那么是不会输出来的;我们再来看一个有用的东西,先吧Birthday的DataMember回复,然后修改成如下代码:

     1 [DataContract]
     2     public class MoStudent
     3     {
     4         [DataMember(Order = 3)]
     5         public DateTime Birthday { get; set; }
     6 
     7         [DataMember(Order = 0)]
     8         public int Id { get; set; }
     9 
    10         [DataMember(Order = 1)]
    11         public string Name { get; set; }
    12 
    13         [DataMember(Order = 2)]
    14         public bool Sex { get; set; }
    15 
    16     }

    然后咋们再运行起来看效果图:

    相信仔细的朋友能够发现,此时Birthday数据暂时的位置已经从第一个变到了最后一个,没错这就是DataMember中Order属性参数的效果:用来指定显示输出数据的位置;

    好了咋们来看正题,webapi返回json数据这里讲解两种,一种是使用自带的Json格式化方式,使用方法只需要在 Global.asax.cs 文件中清除一下默认的xml输出方式即可,代码如:

    
    

    在全局设置中,把所有返回的格式清除,设置JSON。所有的返回的xml格式都会被清除

    在WebApiConfig类的Register方法中,我们添加下面代码:

    config.Formatters.Clear();
    config.Formatters.Add(new JsonMediaTypeFormatter());

    因为webapi在启动的时候,默认格式化数据有两种方式xml和json,而xml是其默认的启动方式,所以这里是需要清除了xml格式化,那么另外只剩下json,所以咋们在运行程序后能看到这样的结果输出:

    结果返回了json数据,如果咋们想要如上面xml一样吧Birthday隐藏掉,我们同样也可以使用 DataContract 和 DataMember 来做这效果,删除Birthday对应的 DataMember 标记后,咋们能看到这样的效果:

    同理,我们把Birthday的DataMember还原,然后指定Order属性值 [DataMember(Order=1)] ,这样Birthday显示的位置就变动了:

    好了这试第一种json格式化的方式,下面来看下用使用Json.Net怎么来格式化,为了避免影响效果,我们把 Global.asax.cs 文件还原,然后重新增加一个Action方法,代码如:

     1 [Route("all01_1")]
     2         public async Task<HttpResponseMessage> GetAllStudents01_1()
     3         {
     4             var result = await JsonConvert.SerializeObjectAsync(students);
     5 
     6             return new HttpResponseMessage
     7             {
     8                 Content = new StringContent(result),
     9                 StatusCode = HttpStatusCode.OK
    10             };
    11         }

    这里用到了Json.Net的 JsonConvert.SerializeObjectAsync 方法来格式化成字符串,然后传递给 HttpResponseMessage ,最终输出的效果和上面一样,好了咋们也来看看这种方式怎么来隐藏不希望接口暴露的属性,这里我们用 JsonIgnore 标记,测试用例在实体类中修改如:

    1 [JsonIgnore]
    2 public DateTime Birthday { get; set; }

    然后运行看一下效果:

    我们再来看一下怎么来设置属性的排序,可以使用 JsonProperty(Order = 1) ,实体类修改的代码如下:

     1 public class MoStudent
     2     {
     3         //[DataMember(Order = 1)]
     4         [JsonProperty(Order = 1)]
     5         public DateTime Birthday { get; set; }
     6 
     7         //[DataMember(Order = 0)]
     8         [JsonProperty(Order = 0)]
     9         public int Id { get; set; }
    10 
    11         //[DataMember(Order = 1)]
    12         [JsonProperty(Order = 1)]
    13         public string Name { get; set; }
    14 
    15         //[DataMember(Order = 2)]
    16         [JsonProperty(Order = 2)]
    17         public bool Sex { get; set; }
    18 
    19     }

    能得到和DataMember设置的一样的结果:

     

    . json时间格式处理方式

    要说时间格式化,我们通常的生日格式如:yyyy-MM-dd这样,下面也分别对刚才上面两种json化出来的时间做格式化;先来看Json.net,我们先来定义一个名称为 SelfDateTimeFormat 的类并且继承 DateTimeConverterBase 类,然后需要重写 ReadJson和WriteJson ,下面看下这个类的全部方法:

     1  /// <summary>
     2         /// 自定义时间格式化
     3         /// </summary>
     4         public class SelfDateTimeFormat : DateTimeConverterBase
     5         {
     6             public IsoDateTimeConverter TimeConvert = null;
     7 
     8             public SelfDateTimeFormat() {
     9 
    10                 TimeConvert = new IsoDateTimeConverter
    11                 {
    12                     DateTimeFormat = "yyyy-MM-dd"
    13                 };
    14             }
    15 
    16             public SelfDateTimeFormat(string formatter = "yyyy-MM-dd HH:mm:ss")
    17             {
    18 
    19                 TimeConvert = new IsoDateTimeConverter
    20                 {
    21                     DateTimeFormat = formatter
    22                 };
    23             }
    24 
    25             public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    26             {
    27 
    28                 return TimeConvert.ReadJson(reader, objectType, existingValue, serializer);
    29             }
    30 
    31             public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    32             {
    33 
    34                 TimeConvert.WriteJson(writer, value, serializer);
    35             }
    36         }

    然后我们需要在实体类的时间属性上增加这样的标记: [JsonConverter(typeof(OverridClass.SelfDateTimeFormat))] ,这里的 SelfDateTimeFormat 就是咋们刚才定义的自定义格式化时间类,我们来看一下输出的效果数据:

    好了,咋们再来看webapi自带的json格式化如何定义一个日期格式的数据,我们需要在Global.asax.cs中增加如下代码:

    1 var format = GlobalConfiguration.Configuration.Formatters;
    2             format.JsonFormatter.SerializerSettings.DateFormatString = "yyyy.MM.dd";

    没错,只需要如此简单的代码,即可时间格式化成:

     

    . 让api接口支持返回json和xml数据

    开篇第一小节已经有简单说明webapi有自己的json和xml格式化处理,这里们来设置通过参数请求返回不同的数据格式;首先还是需要在Global中设置如下代码:

    1  var format = GlobalConfiguration.Configuration.Formatters;
    2             format.JsonFormatter.SerializerSettings.DateFormatString = "yyyy.MM.dd";
    3 
    4             //清除默认xml
    5             format.XmlFormatter.SupportedMediaTypes.Clear();
    6          
    7             //通过参数设置返回格式
    8             format.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("t", "json", "application/json"));
    9             format.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("t", "xml", "application/xml"));

    这里用到了 QueryStringMapping 类,并传递给他构造函数的参数 new QueryStringMapping("t","json""application/json") 和 new QueryStringMapping("t""xml""application/xml") 这样就分别对用了json和xml,而前面的“t”表示请求的url地址中参数名称t,下面我们分别来测试下两种请求的参数,地址分别为:

     http://localhost:1001/s/all01?t=xml 

     

     http://localhost:1001/s/all01?t=json 

     

    展开全文
  • ASP.NET web API项目添加日志文件输出

    千次阅读 2018-07-24 18:32:14
    ASP.NET web API项目添加日志输出与C#日志输出存在一点小小的差异,C#中只需要放配置文件就可以了,而ASP.NET log需要配置并在启动文件中加入启动读取配置文件和相关的日志过滤器。在C#和ASP.NET中使用的日志包是log...

    ASP.NET web API项目添加日志输出与C#日志输出存在一点小小的差异,C#中只需要放配置文件就可以了,而ASP.NET log需要配置并在启动文件中加入启动读取配置文件和相关的日志过滤器。在C#和ASP.NET中使用的日志包是log4net。

    C# 日志配置

    只需要编辑一个log4.config文件到bin的对应版本下就可以了。

    <?xml version="1.0"?>
    <configuration>
      <log4net>
        <root>
          <level value="DEBUG" />
          
        </root>
        <logger name="SQ">
          <level value="DEBUG"/>
            <appender-ref ref="RollingFileAppender" />
        </logger>
          <logger name="ErrLog">
              <level value="DEBUG"/>
              <appender-ref ref="LogForError" />
          </logger>
        <appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
          <param name="File" value="LogFile/log-file.txt" />
          <param name="AppendToFile" value="true" />
          <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c [%x]  - %m%n" />
          </layout>
        </appender>
        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
          <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
          </layout>
        </appender>
        <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
          <!--日志文件名-->
          <file value="LogFile/log-file.txt"/>
          <!--是否在文件中追加-->
          <appendToFile value="true"/>
          <!--按照文件的大小进行变换日志文件-->
          <rollingStyle value="Size"/>
          <!--最大变换数量-->
          <maxSizeRollBackups value="100"/>
          <!--最大文件大小-->
          <maximumFileSize value="10MB"/>
          <!--日志文件名是否为静态-->
          <staticLogFileName value="false"/>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d [%t] %-5p %c [%x]  - %m%n" />
          </layout>
        </appender>
          <appender name="LogForError" type="log4net.Appender.RollingFileAppender">
              <!--日志文件名-->
              <file value="Error_log/"/>
              <datePattern value="&quot;Error_&quot;yyyyMMdd&quot;.log&quot;"/>
              <!--是否在文件中追加-->
              <appendToFile value="true"/>
              <!--按照文件的大小进行变换日志文件-->
              <rollingStyle value="Composite" />
              <!--最大变换数量-->
              <maxSizeRollBackups value="100"/>
              <!--最大文件大小-->
              <maximumFileSize value="10MB"/>
              <!--日志文件名是否为静态-->
              <staticLogFileName value="false"/>
              <layout type="log4net.Layout.PatternLayout">
                  <conversionPattern value="%d [%t] %-5p %c [%x]  - %m%n" />
              </layout>
          </appender>
    
      </log4net>
    </configuration>
    

    ASP.NET 日志相关工具类

    在项目中新建一个Logs文件夹,然后添加如下几个类到里面:

    LoggerHelper.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace RTVSApiFD.Logs
    {
        /// <summary>
        /// 日志帮助类
        /// </summary>
        public class LoggerHelper
        {
            private static readonly log4net.ILog LogInfo = log4net.LogManager.GetLogger("LogInfo");
    
            private static readonly log4net.ILog LogError = log4net.LogManager.GetLogger("LogError");
    
            private static readonly log4net.ILog LogMonitor = log4net.LogManager.GetLogger("LogMonitor");
    
            /// <summary>
            /// 记录Error日志
            /// </summary>
            /// <param name="errorMsg"></param>
            /// <param name="ex"></param>
            public static void Error(string errorMsg, Exception ex = null)
            {
                if (ex != null)
                {
                    LogError.Error(errorMsg, ex);
                }
                else
                {
                    LogError.Error(errorMsg);
                }
            }
    
            /// <summary>
            /// 记录Info日志
            /// </summary>
            /// <param name="msg"></param>
            /// <param name="ex"></param>
            public static void Info(string msg, Exception ex = null)
            {
                if (ex != null)
                {
                    LogInfo.Info(msg, ex);
                }
                else
                {
                    LogInfo.Info(msg);
                }
            }
    
            /// <summary>
            /// 记录Monitor日志
            /// </summary>
            /// <param name="msg"></param>
            public static void Monitor(string msg)
            {
                LogMonitor.Info(msg);
            }
        }
    }

    MonitorLog.cs

    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Diagnostics;
    using System.Linq;
    using System.Web;
    
    namespace RTVSApiFD.Logs
    {
        /// <summary>
        /// 监控日志对象
        /// </summary>
        public class MonitorLog
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            public MonitorLog()
            {
                this.Watch = new Stopwatch();
                this.Watch.Start();
            }
    
            /// <summary>
            /// 监控类型
            /// </summary>
            public enum MonitorType
            {
                /// <summary>
                /// Action
                /// </summary>
                Action = 1,
    
                /// <summary>
                /// 视图
                /// </summary>
                View = 2
            }
    
            /// <summary>
            /// 
            /// </summary>
            public string ControllerName { get; set; }
    
            /// <summary>
            /// 
            /// </summary>
            public string ActionName { get; set; }
    
            /// <summary>
            /// 
            /// </summary>
            public Stopwatch Watch { get; set; }
    
            /// <summary>
            /// 
            /// </summary>
            public DateTime ExecuteStartTime { get; set; }
    
            /// <summary>
            /// 
            /// </summary>
            public DateTime ExecuteEndTime { get; set; }
    
            /// <summary>
            /// Form 表单数据
            /// </summary>
            public NameValueCollection FormCollections { get; set; }
    
            /// <summary>
            /// URL 参数
            /// </summary>
            public NameValueCollection QueryCollections { get; set; }
    
            /// <summary>
            /// 文本流
            /// </summary>
            public string Raw { get; set; }
    
            /// <summary>
            /// 获取监控指标日志
            /// </summary>
            /// <param name="mtype"></param>
            /// <returns></returns>
            public string GetLogInfo(MonitorType mtype = MonitorType.Action)
            {
                this.Watch.Stop();
                string actionView = "Action执行时间监控:";
                string action = "Action";
                if (mtype == MonitorType.View)
                {
                    actionView = "View视图生成时间监控:";
                    action = "View";
                }
                string msgContent = string.Format(@"{0}ControllerName:{1}Controller {2}Name:{3} 开始时间:{4}  结束时间:{5} 总 时 间:{6}秒",
                    actionView,
                    this.ControllerName,
                    action,
                    this.ActionName,
                    this.ExecuteStartTime,
                    this.ExecuteEndTime,
                    this.Watch.ElapsedMilliseconds);
    
                if (!string.IsNullOrEmpty(this.Raw))
                {
                    msgContent += @"
            Raw:" + this.Raw;
                }
                else if (this.FormCollections != null)
                {
                    msgContent += @"
            Form:" + this.GetCollections(this.FormCollections);
                }
                else if (this.QueryCollections != null)
                {
                    msgContent += @"
            Query:" + this.GetCollections(this.QueryCollections);
                }
    
                return msgContent;
            }
    
            /// <summary>
            /// 获取Post 或Get 参数
            /// </summary>
            /// <param name="collections"></param>
            /// <returns></returns>
            public string GetCollections(NameValueCollection collections)
            {
                string parameters = string.Empty;
                if (collections == null || collections.Count == 0)
                {
                    return parameters;
                }
                parameters = collections.Keys.Cast<string>()
                    .Aggregate(parameters, (current, key) => current + string.Format("{0}={1}&", key, collections[key]));
                if (!string.IsNullOrWhiteSpace(parameters) && parameters.EndsWith("&"))
                {
                    parameters = parameters.Substring(0, parameters.Length - 1);
                }
                return parameters;
            }
        }
       }

    TrackerFilter.cs

    
    
    using System;
    using System.Globalization;
    using System.Web.Mvc;
    
    namespace RTVSApiFD.Logs
    {
        
        /// <summary>
        /// 跟踪过滤器
        /// </summary>
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class TrackerFilter : System.Web.Mvc.ActionFilterAttribute,System.Web.Mvc.IActionFilter,System.Web.Mvc.IResultFilter,System.Web.Mvc.IExceptionFilter
        {
            private readonly string key = "_thisOnActionMonitorLog_";
    
            #region Action时间监控
            /// <summary>
            /// OnActionExecuting
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                MonitorLog monLog = new MonitorLog();
                monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo));
                monLog.ControllerName = filterContext.RouteData.Values["controller"] as string;
                monLog.ActionName = filterContext.RouteData.Values["action"] as string;
                filterContext.Controller.ViewData[this.key] = monLog;
            }
    
            /// <summary>
            /// OnActionExecuted
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                monLog.FormCollections = filterContext.HttpContext.Request.Form;//form表单提交的数据
                monLog.QueryCollections = filterContext.HttpContext.Request.QueryString;//Url 参数
                LoggerHelper.Monitor(monLog.GetLogInfo());
            }
            #endregion
    
            #region View 视图生成时间监控
            /// <summary>
            /// OnResultExecuting
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteStartTime = DateTime.Now;
            }
    
            /// <summary>
            /// OnResultExecuted
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                LoggerHelper.Monitor(monLog.GetLogInfo(MonitorLog.MonitorType.View));
                filterContext.Controller.ViewData.Remove(this.key);
            }
            #endregion
    
            #region 错误日志
            /// <summary>
            /// OnException
            /// </summary>
            /// <param name="filterContext"></param>
            public void OnException(ExceptionContext filterContext)
            {
                if (!filterContext.ExceptionHandled)
                {
                    string controllerName = string.Format("{0}Controller", filterContext.RouteData.Values["controller"] as string);
                    string actionName = filterContext.RouteData.Values["action"] as string;
                    string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
                    LoggerHelper.Error(errorMsg, filterContext.Exception);
                }
            }
    
            /// <summary>
            /// OnAuthorization
            /// </summary>
            /// <param name="filterContext"></param>
            public void OnAuthorization(AuthorizationContext filterContext)
            {
                这个方法是在Action执行之前调用
                //var user = filterContext.HttpContext.Session["userName"];
                //if (user == null)
                //{
                //    //filterConetext.HttpContext.Response.Redirect("/Login/index");
                //    var url = new UrlHelper(filterContext.RequestContext);
                //    var urls = url.Action("Index", "Login");
                //    filterContext.Result = new RedirectResult(urls);
                //}
            }
            #endregion
        }
    }

    ApiTrackerFilter.cs

    using System;
    using System.Globalization;
    using System.Web.Mvc;
    
    namespace RTVSApiFD.Logs
    {
        /// <summary>
        /// API过滤器
        /// </summary>
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class ApiTrackerFilter : System.Web.Mvc.ActionFilterAttribute, System.Web.Mvc.IActionFilter, System.Web.Mvc.IResultFilter, System.Web.Http.Filters.IFilter
        {
            private readonly string key = "_thisOnApiActionMonitorLog_";
    
    
            #region Action时间监控
            /// <summary>
            /// OnActionExecuting
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                MonitorLog monLog = new MonitorLog();
                monLog.ExecuteStartTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ffff", DateTimeFormatInfo.InvariantInfo));
                monLog.ControllerName = filterContext.RouteData.Values["controller"] as string;
                monLog.ActionName = filterContext.RouteData.Values["action"] as string;
                filterContext.Controller.ViewData[this.key] = monLog;
            }
    
            /// <summary>
            /// OnActionExecuted
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                monLog.FormCollections = filterContext.HttpContext.Request.Form;//form表单提交的数据
                monLog.QueryCollections = filterContext.HttpContext.Request.QueryString;//Url 参数
                LoggerHelper.Monitor(monLog.GetLogInfo());
            }
            #endregion
    
            #region View 视图生成时间监控
            /// <summary>
            /// OnResultExecuting
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuting(ResultExecutingContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteStartTime = DateTime.Now;
            }
    
            /// <summary>
            /// OnResultExecuted
            /// </summary>
            /// <param name="filterContext"></param>
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                MonitorLog monLog = filterContext.Controller.ViewData[this.key] as MonitorLog;
                monLog.ExecuteEndTime = DateTime.Now;
                LoggerHelper.Monitor(monLog.GetLogInfo(MonitorLog.MonitorType.View));
                filterContext.Controller.ViewData.Remove(this.key);
            }
            #endregion
    
            #region 错误日志
            /// <summary>
            /// OnException
            /// </summary>
            /// <param name="filterContext"></param>
            public void OnException(ExceptionContext filterContext)
            {
                if (!filterContext.ExceptionHandled)
                {
                    string controllerName = string.Format("{0}Controller", filterContext.RouteData.Values["controller"] as string);
                    string actionName = filterContext.RouteData.Values["action"] as string;
                    string errorMsg = string.Format("在执行 controller[{0}] 的 action[{1}] 时产生异常", controllerName, actionName);
                    LoggerHelper.Error(errorMsg, filterContext.Exception);
                }
            }
    
            /// <summary>
            /// OnAuthorization
            /// </summary>
            /// <param name="filterContext"></param>
            public void OnAuthorization(AuthorizationContext filterContext)
            {
                这个方法是在Action执行之前调用
                //var user = filterContext.HttpContext.Session["userName"];
                //if (user == null)
                //{
                //    //filterConetext.HttpContext.Response.Redirect("/Login/index");
                //    var url = new UrlHelper(filterContext.RequestContext);
                //    var urls = url.Action("Index", "Login");
                //    filterContext.Result = new RedirectResult(urls);
                //}
            }
            #endregion
        }
    }

    测试ASP..NET相关设置

    在Global.asax文件中添加读取日志的配置

    using JT1078Server;
    using log4net.Config;
    using RedisHelp;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    
    namespace RTVSApiFD
    {
        /// <summary>
        /// 全局启动类
        /// </summary>
        public class WebApiApplication : System.Web.HttpApplication
        {
    
            /// <summary>
            /// Redis帮助类初始化
            /// </summary>
            public static RedisHelper RedisHelper = new RedisHelper();
    
            /// <summary>
            /// 音视频服务
            /// </summary>
            public static Task TaskService = new Task();
    
            /// <summary>
            /// 启动web程序
            /// </summary>
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                GlobalConfiguration.Configure(WebApiConfig.Register);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                //应用程序启动时,自动加载配置log4Net
                log4net.Config.XmlConfigurator.Configure();
                GlobalConfiguration.Configuration.Filters.Add(new Logs.ApiTrackerFilter());
            }
        }
    }
    

    此时还需要修改FilterConfig类,添加注册过滤器:

    using System.Web;
    using System.Web.Mvc;
    
    namespace RTVSApiFD
    {
        /// <summary>
        /// 过滤器配置
        /// </summary>
        public class FilterConfig
        {
            /// <summary>
            /// 注册全局过滤器
            /// </summary>
            /// <param name="filters"></param>
            public static void RegisterGlobalFilters(GlobalFilterCollection filters)
            {
                //API日志
                filters.Add(new Logs.ApiTrackerFilter());
                //监控日志
                filters.Add(new Logs.TrackerFilter());
    
                filters.Add(new HandleErrorAttribute());
            }
        }
    }
    

    修改web.config文件加入日志配置:

    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
      </configSections>
    
      <log4net>
        <!--错误日志-->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="log\\LogError\\" />
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
          <staticLogFileName value="false" />
          <param name="MaxSizeRollBackups" value="100" />
          <layout type="log4net.Layout.PatternLayout">
            <!--每条日志末尾的文字说明-->
            <!--输出格式-->
            <!--样例:2008-03-26 13:42:32,111 [10] INFO  Log4NetDemo.MainClass [(null)] - info-->
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n错误描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--Info日志-->
        <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\\LogInfo\\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n日志描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--监控日志-->
        <appender name="MonitorAppender" type="log4net.Appender.RollingFileAppender">
          <param name="File" value="Log\\LogMonitor\\" />
          <param name="AppendToFile" value="true" />
          <param name="MaxFileSize" value="10240" />
          <param name="MaxSizeRollBackups" value="100" />
          <param name="StaticLogFileName" value="false" />
          <param name="DatePattern" value="yyyy\\yyyyMM\\yyyyMMdd'.txt'" />
          <param name="RollingStyle" value="Date" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n跟踪描述:%message%newline %n" />
          </layout>
        </appender>
    
        <!--Error日志-->
        <logger name="LogError">
          <level value="ERROR" />
          <appender-ref ref="RollingLogFileAppender" />
        </logger>
    
        <!--Info日志-->
        <logger name="LogInfo">
          <level value="INFO" />
          <appender-ref ref="InfoAppender" />
        </logger>
    
        <!--监控日志-->
        <logger name="LogMonitor">
          <level value="Monitor" />
          <appender-ref ref="MonitorAppender" />
        </logger>
      </log4net>
    
    <configuration>

     

    测试ASP..NET日志输出

    编写一个简单的API测试,下面是API的一个方法:

      [HttpPost]
            public Result MultiSIMAlarmForJsonParam(FileSourceMultiRequest fileSourceMultiRequest)
            {
                Result result = null;
                try
                {
                    if (fileSourceMultiRequest != null)
                    {
                        LoggerHelper.Monitor("MultiSIMAlarmForJsonParam:" + fileSourceMultiRequest.ToJson());
                        LoggerHelper.Info("MultiSIMAlarmForJsonParam:" + fileSourceMultiRequest.ToJson());
                        List<AVInfo> list = cache.QueryMulti(fileSourceMultiRequest.Sims, fileSourceMultiRequest.Channel, fileSourceMultiRequest.Alarms, fileSourceMultiRequest.StorageType, fileSourceMultiRequest.StreamType, fileSourceMultiRequest.StartTime.DateTimeToUNIX_long(), fileSourceMultiRequest.EndTime.DateTimeToUNIX_long(),fileSourceMultiRequest.DataType);
                        LoggerHelper.Info("MultiSIMAlarmForJsonParam:list.size=" + (list == null ? 0 : list.Count));
                        if (list != null)
                        {
                            result = new Result(1, "查询成功!", list);
                        }
                        else
                        {
                            result = new Result(0, "没有查询到结果!", new List<AVInfo>());
                        }
                        LoggerHelper.Info("Result=" + result.ToJson());
                    }
                }
                catch (Exception ex)
                {
                    result = new Result(2, "异常:" + ex.Message, new List<AVInfo>());
                    LoggerHelper.Error("MultiSIMAlarmForJsonParam异常:" + result.ToJson());
                }
                return result;
            }

    查看日志(运行的时候回自动创建日志路径):

    自此,日志就配置完成了!

    参考文章:https://www.cnblogs.com/huanghzm/p/4754890.html

    展开全文
  • Web实时日志输出查看管理系统

    万次阅读 2019-04-03 18:17:30
    开发人员无权限访问生产服务器,怎样查看日志来分析问题? 安全管理合规的原因,开发未被授权访问...开源产品 logiohttp://logio.org/可实时采集日志通过 web 展示 , 应用多了,日志多了分类浏览不便,无法解决持久存储...

    开发人员无权限访问生产服务器,怎样查看日志来分析问题?

    安全管理合规的原因,开发未被授权访问生产服务器,但经常会有分析问题查看日志的需求. 大家一般是怎样解决的?

    我尝试用过的,或者是想到的方法主要有如下几种,但都不太完美,有更好的方案或者工具吗?

    • 开源产品 logio http://logio.org/ 可实时采集日志通过 web 展示 , 应用多了,日志多了分类浏览不便,无法解决持久存储的问题
    • fluented 同步日志文本,以文本模式存储在专用的日志服务器.
    • 系统管理员手工复制日志
    • jenkins + ansible+shell 脚本 复制传输日志
    • 使用ELK 处理过多行文本,比如 tomcat 的日志
    • 利用linux服务器系统自带的rsyslog+php进行日志采集
    • 搭建FTP映射虚拟目录指向日志目录(前提只开读权限)
    • 考虑 log 实时上传到云上或者同步到一台专门的日志服务器上

    今天我们要介绍一款实时同步分析日志的web管理工具Log.io  让我们一起感受一哈Websocket的魅力。

    Node.js中使用Log.io在浏览器中实时监控日志,Log.io等同于tail -f命令,但更强大(web+node展示)

    官方介绍:http://logio.org/

    GitHub源码:https://github.com/NarrativeScience/Log.io

    日志是个好东西,对技术人员来说写日志能纪录成长,分享经验;对机器来说纪录日志能及时发现错误,为日后的排错提供信息。如果还在一台机器上用 tail -f 监听单个日志或者用 multitail 监听多个日志也太 out 了,我们需要一种工具能纪录上百台机器、不同类型的日志,并最好能汇集到一个界面里方便查看,最好还是实时的。

    log.io 是一个实时日志监控工具,采用 node.js + socket.io 开发,使用浏览器访问,每秒可以处理超过5000条日志变动消息。有一点要指出来的是 log.io 只监视日志变动并不存储日志,和其他的监控工具一样,log.io 也采用服务器-客户端的模式。

    log.io 由两部分组成:server 和 harvester

    server 运行在机器 A(服务器)上监视和纪录其他机器发来的日志消息;

    log harvester 运行在机器 B(客户端)上用来监听和收集机器 B 上的日志改动,并将改动发送给机器 A,每个需要纪录日志的机器都需要一个 harvester.

    在A和B两台机器上同时安装(第一步到第四步)

    一、安装依赖包

    yum install gcc gcc-c++ openssl-devel  pkgconfig -y
    

    二、下载 node.js 源代码,编译并安装:

    wget http://nodejs.org/dist/v0.8.14/node-v0.8.14.tar.gz
    tar xf node-v0.8.14/
    ./configure
    make
    make install
    

    三、安装NPM

    wget https://npmjs.org/install.sh && sh install.shsi
    

    四、安装 log.io(包含了 log server 和 log harvester)

    npm config set unsafe-perm true

    npm install -g --prefix=/usr/local log.io

    注意:第二部安装的时候安装时间较长(基于网络下载软件包),请耐心等待!!

     

    五、在服务端(A节点)上启动server

    cd node-v0.8.14
    log.io-server start
    

    六、在客户端(B节点)配置

    vim /root/.log.io/harvester.conf
    exports.config = {
      nodeName: "nodeB",          ####修改节点名称(自定义)
      logStreams: {
        nginx_access: [                  ####日志服务的名称(自定义)
          "/var/log/nginx/access.log",  ###日记存储路径
        ],
        nginx_error: [                  ####日志服务的名称(自定义)
           "/var/log/nginx/error.log"     ###日记存储路径
        ]
      },
      server: {
        host: '10.10.0.2',      ####log.io Server端的IP
        port: 28777              ####log.io Server端的端口(默认端口)
      }
    }

     

    七、在客户端(B节点)启动服务

    cd node-v0.8.14
    log.io-harvester start
    

    八、通过游览器查看日记实时信息

    附录Windows部署请参考:https://www.cnblogs.com/loveclumsybaby/p/10622974.html

    Log.IO能做什么

    这个软件的功能非常简单,对的,非常简单!不像Zabbix一样具备非常多的隐藏技能,安装过程非常简单.

    npm install -g log.io --user "root"
    //启动server
    log.io-server
    //修改一下配置,主要改服务器信息和日志路径
    vi ~/.log.io/harvester.conf
    //启动采集器
    log.io-harvester
    //访问页面
     http://localhost:28778
    

    Paste_Image.png

    他就提供了一个看实时日志的界面(原谅我突然就开启了吐槽模式,你这会不会也太简单了一点),不过总的来说,问题还是能解决的,左侧的菜单思路是节点->应用名这样的模式,这个倒是挺正派的,一个节点底下会有多份不同的日志(话说作者不知道有没考虑过给节点分个组呢),右侧的就是应用了,勾选的日志信息都会在这里展现出来,其实单服务器的话倒是没什么问题,但是多服务器,刷日志又刷的快的情况下,这个界面就会看的眼花缭乱了。

    Log.IO源码分析

    站在巨人的肩膀上(有现成的就拿来抄)的思想是我一直所坚持的(这才是生产力啊!ヽ( ∀)ノ),先看整体架构,直接上官方架构图

    Paste_Image.png

    做法是通过Harvester进行日志采集,通过TCP送到Server,然后Server通过WebSocket送到web页面上面。

    Harvester的运转方式

    • 记录指定日志文件的Current Position,然后监控日志文件的变化(NodeJS本身就挺多这样的库的),每当发生Change事件之后,往下读文件
    • 把变更的文件通过一定的格式采用TCP协议送到Server端
    +log|web_server|my_server01|info|this is log messages
    

    Server的运作方式

    Server在接受到Harvester送来的的信息之后,把字符串变成LogObject、LogStream、LogNode等一系列对象

    通过Socket.IO这个库把日志信息往外送,Socket.IO这个库倒是挺简单易用的,上个官网例子

    var io = require('socket.io')(80);
    var cfg = require('./config.json');
    var tw = require('node-tweet-stream')(cfg);
    tw.track('socket.io');
    tw.track('javascript');
    tw.on('tweet', function(tweet){
      io.emit('tweet', tweet);
    });
    

    Web

    Web的开发上倒是挺中规中矩的,采用比较流行的Express,然后通过WebSocket接收完数据之后就把对应的数据显示在页面上

    一些想法

    Log.IO这个应用代码量非常的少,这种易读性使得这个程序非常适合拿来改造(比起读Kibana那界面的原源码,这简直就是天堂T_T),所以,不由的就产生了一些想法

    对Harvester的一些想法

    按照Harvester的运作方式来看,我认为完全可以不采用log.io的Harvester,而直接采用类似Rsyslog这样的大多数操作系统上都存在的日志收集工具就可以了,免去Agent部署升级的烦恼。不然还不知道会不会碰上Agent性能不稳定搞挂服务器呢

    对Server的一些想法

    既然是WebSocket,那么是不是可以采用类似在Nginx上加WebSocket扩展之类的做法来把Server替换掉呢?

    log.io是不是能够集成到ELK这类日志搜索软件里面,作为辅助功能存在呢?日志先送到ES或者是一些其他地方,然后再通过一些Transfer程序把日志送到Server

    对Web的一些想法

    Web这种操作上的东西,应各业务场景(个人品味。。。)不同会有比较大的差别,假如是我设计这个功能的原型,我会希望页面上能有这样的功能。

    • 实时日志按照时间分屏展示;
    • 能够在界面上输入关键字,然后对关键字日志高亮,方便排查问题;
    • 再多一个业务模块的分组,方便对整组业务模块的服务器进行过滤;
    • 根据提供的关键字信息,只展示具备关键字的日志行(类似tail -f xxx|grep 这样的功能);

    websocket技术,在运维工具的浏览器上实时显示远程服务器上的日志信息

    一般我们在运维工具部署环境的时候,需要实时展现部署过程中的信息,或者在浏览器中实时显示程序日志给开发人员看。你还在用ajax每隔段时间去获取服务器日志?out了,试试用websocket方式吧。

    【参考文档】

    1、Log.IO的使用场景和改造思路 - 简书 https://www.jianshu.com/p/c301cae2f394

    2、运维开发:python websocket网页实时显示远程服务器日志信息 -  https://www.cnblogs.com/php-rearch/p/6661241.html

    3、如何把Tomcat的日志实时输出到Web页面上_https://www.linuxidc.com/Linux/2015-02/113356.htm

    4、网页中实时查看服务器日志(websocket + node.js实现) https://blog.csdn.net/definite_things/article/details/43058919

    5、Java用WebSocket + tail命令实现Web实时日志 -https://blog.csdn.net/xiao__gui/article/details/50041673

    6、个人开发者的服务器日志收集 - https://soulteary.com/2018/06/13/server-log-collection-for-individual-developers.html

    7、日志服务器应用开发 - vitaair的博客 - CSDN博客 https://blog.csdn.net/vitaair/article/details/80220619

    8、网站用户行为日志采集和后台日志服务器搭建 - https://blog.csdn.net/weixin_37490221/article/details/80894827

    9、windows下,Kiwi_Syslog日志服务器的搭建 - https://blog.csdn.net/McYaoYao/article/details/78225466

    10、远哥谈 使用WebSocket开发在线实时看远程服务器log日志的工具 - https://www.cnblogs.com/taven/p/3483002.html

     

    展开全文
  • 一个简单需求,就是通过logstash(后期也会使用flume)接入数据,并且解析数据输入到webHDFS,根据获取系统日志产生的时间进行自动分年月日存储数据分区 第一步: 测试日志例子: conf文件input内容: ...
  • spring boot集成WebSocket实时输出日志到web页面

    万次阅读 热门讨论 2017-11-22 21:36:49
    今天来做个有趣的东西,就是实时将系统日志输出的前端web页面,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot中,使用websocket超级方便,阅读本文,你会接触到以下关键词相关技术,...
  • 用SVG技术实现动态图形输出的嵌入式Web服务 来源:网络收集 作者: 时间:2007-06-06 点击: 632 摘 要 本文结合控制系统对嵌入式Web服务器的要求,分析了嵌入式Web服务器的...
  • 解决asp.net输出时间格式带T问题

    千次阅读 2018-09-14 10:56:41
    当使用webapi输入时间结果时,会发现结果会带有T,列入2018-09-14T10:51:20.255,其实解决这个问题,我们只需要在WebApiConfig中添加下面代码即可解决: GlobalConfiguration.Configuration.Formatters.Json...
  • 线上环境的log输出级别一般都设置的很高比如WARN,如果出现一些很难直观解决的问题,可能需要调整日志输出级别为DEBUG,又不想改个日志输出级别还要重启服务,那么可以考虑一下如下方法: 通过在web.xml中添加如下...
  • //获取输出流 PrintWriter out = response.getWriter(); //获取当前系统时间 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 String t=df.format(new Date());// new Date...
  • java web 项目中的时间处理

    千次阅读 2017-11-01 09:41:06
    从数据库来看,简单关系数据库mysql存储了四种种时间类型,timestamp,time,date以及datetime,分别对应于1970年至今所经过的秒数,时-分秒,年-月-日与年-月-日-时-分-秒。 在后台通过@Temporal(TemporalType....
  • java web显示系统时间

    千次阅读 2020-06-23 23:01:11
    -- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 在JSP页面中输出完整的时间,格式为:“年 月 日 时:分:秒” (); String year = String.format("%tY", date...
  • 此时弹出一个窗口,在左边栏选择Maven,稍等一段时间加载之后,右侧会出现一列archetype。勾选Create from archtype,找到并选择org.apache.maven.archtypes:maven-archtype-webapp,点击Next。 二、填写这个...
  • web 前段 jstl 格式化时间 及数字

    千次阅读 2012-10-18 17:49:56
    添加标签引用: 对应uri:http://java.sun.com/jstl/fmt_rt 还有 对应uri:http://java.sun.com/jsp/jstl/fmt 对应tld文件就是/WEB-INF/fmt-1_0-rt.tld 格式化时间输出:11.00输出:11
  • web网站显示当前时间

    千次阅读 2017-12-07 17:47:04
    var week = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); var now = new Date(); var year = now.getFullYear(); var month = now.getMonth() + 1;...var day = now.getDate...
  • OK,现在我们来整理下log4j来web项目中的应用。我之前搞了2年web,使用的日志都是log4j。关于现在比较火的logback我后面会有博客整理到,不管怎么样,这里先整理一下web中log4j的使用,特别是log4j.xml,之后如果...
  • //指定服务器输出内容的编码方式为utf-8,防止乱码 resp.setContentType("text/html;charset=utf-8"); String lastaccesstime=null; //获取所有cookie,并将这些cookie存放在数组中 Cookie[] cookies=req.get...
  • Web应用程序  (1)什么是Web应用程序  应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。而B/S就是浏览 器端/服务器端应用程序,这类应用程序一般借助浏览器来运行。 ...
  • ASP.NET Web API 接口执行时间监控

    千次阅读 2015-08-05 09:44:26
    ASP.NET Web API 接口执行时间监控 软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥。如何快速有效地找到软件产品的性能瓶颈,则是...
  • Servlet(一)输出时间到浏览器

    千次阅读 2018-03-28 20:21:00
    由于客户端是通过URL访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把Servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用 和元素完成。 元素用于注册Servlet,它包含有两个主要的子元素...
  • Web应用测试监控执行时间 -- JavaSimon

    千次阅读 2015-02-07 16:04:49
    JavaSimon是一个很不错的性能监控lib。不仅可以方便的监控数据层,业务层,Web层的各自访问时间,还提供了Web页面查看统计数据和系统告警通知功能,非常不错。
  • 使用Spring Boot开发Web项目

    万次阅读 多人点赞 2016-12-21 17:26:31
    前面两篇博客中我们简单介绍了Spring Boot项目的创建、并且也带小伙伴们来DIY了一个Spring Boot自动配置功能,那么这些东西说到底最终还是要回归到Web上才能体现出它的更大的价值,so,今天我们就来看一下如何使用...
  • 在网站性能的相关工作中,一个重要的方面是... 监控http请求的处理时间的方法有很多,这里介绍一种java(j2ee)的web程序中监控/统计http请求处 理时间的简便方法:就是利用Filter来统计所有请求的处理时
  • Web 事件Web 事件功能为发出运行时事件提供了一个通用框架,用以指示应用程序中发生的值得注意的操作,报告应用程序运行状况或任何其他值得注意的信息。该功能可使管理员通过配置中的事件订阅确切地确定他们感兴趣的...
  • WEB简介

    万次阅读 多人点赞 2018-09-01 18:23:51
    WEB 一、Web简介 1、 简介 早期的web应用主要是静态页面的浏览,这些静态页面使用HTML语言编写,放在服务器上,用户使用浏览器通过HTTP协议请求服务器上的web页面,服务器上的web服务器软件接受到用户发送的...
  • 1. 使用IDE编写、运行一个简单的Servlet。...【步骤2】在该项目的com.demo路径下,使用Servlet模板编写一个简单的Servlet类helloServlet.java,输出一个HTML页面,页面上显示一个一行两列的表格。在WEB-...
  • Web安全

    千次阅读 2012-08-02 17:08:14
    Web系统必须采取措施降低Web应用安全风险。 1.认证模块必须采用防暴力破解机制,例如:验证码或者多次连续尝试登录失败后锁定帐号或IP。 说明:如采用多次连续尝试登录失败后锁定帐号或IP的方式,需支持连续登录...
  • 其实这个Session的控制时间,在以前做...<system.web> 写上这句话,其中timeout的时间为分钟,这里设置为60分钟 <sessionState mode="InProc" timeout="60" cookieless="false"/><br />  既然说Sessi

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 420,974
精华内容 168,389
关键字:

web输出时间