采取OData协议查询Windows日志

 
图片 1OData开放数据协议凡是微软对Google的GData推出的,旨在加大Web程序数据库格式标准化的放数据协议,微软用
OData 定义也依据 HTTP、AtomPub 和 JSON
的商议,增强各种网页应用程序之间的数据兼容性,以提供多行使、服务同数目企业的音讯看。并且,微软一度正式生产了
OData SDK,包含了 .NET、Java、PHP、Palm WebOS 和 iPhone 的支持。其中
.Net OData 客户端基于 Apache 授权开源。微软多款产品都支持 OData 包括
SharePoint Server 2010, Excel 2010, Dynamics 等。

   微软首先替代数据交换协议叫ODBC(开放数据库联网 Open Database
Connectivity),目前仍然可见于window和linux的原生程序支付中,其目的是啊操作系统下之应用程序之间提供联合的多寡交互的API,是函数式的。之后,微软推出了第二代表:OLE
DB,带来了OOP式样的交互API,以及跨网络的数交互的可能性(通过DCOM),OLE
DB 标准的实际实现是平组C++ API 函数,就如ODBC 标准被的ODBC API
一样,不同之是,OLE DB 的API 是吻合COM 标准、基于对象的(ODBC API
则是简简单单的C API)。使用OLE DB API,可以编写能够访问符合OLE DB
标准的任何数据源的应用程序,也堪编写针对某种特定数据存储的询问处理先后(Query
Processor)和游标引擎(Cursor Engine),因此OLE DB
标准其实是确定了数使用者和提供者之间的一致栽应用层的商议(Application-Level
Protocol)。在叙计算时,web应用已是主流,程序要通过HTTP
Request来发表要求,通过HTTP Response来抱结果,ODBC和OLE
DB都已经力不从心以。微软受是开了那个第三代表数据交互协议:OData开放数据协议。

  
于SOA的世界中,最关键之一个概念就是契约(contract)。在提计算的世界中,有关通信的极致要害的定义也是契约。XML具有强大对数据的讲述能力,Atom格式和AtomPub都建立以XML之上,在Google和微软的推动下,也就成为标准。但是,Atom/AtomPub和ODBC/OLEDB这样的审数据交互协议相互较,还享有根本上之贫乏:缺乏数据类型的现实讲述,降低了彼此性能。缺乏针对性数据查询的控制能力,比如返回特定的数码集合的区间,或者说分页能力等等。微软基于EDM模型释出了:OData,这里吧得看出Entity
Framework对于NHibernate这样的ORM的工具不同的战略性考虑。

    在PDC大会上,微软颁布了一个代号为
“Dallas”的社区技术预览(CTP),由Windows Azure 和SQL
Azure构建的音服务,能够给开发者和信息工作者于任何平台上用优质的老三在数据集和内容。“Dallas”也得经应用微软技术自助的商务智能与析存储的数额集。Dallas所运用的多少交互协议便是OData。

   以微软的解决方案面临,是故WCF来拍卖所有程序中的通信,针对数据通信,WCF
Data Services自然是最为好的选取。首先,WCF Data
Services是WCF服务,所以您可利用具有现有的WCF知识。其次,WCF Data
Services已经落实了OData拓扑,于是你得从事为公的多少格式在公的次序中的象征,而休是AtomPub/JSON这些真的当网达到传递的数量格式。再有,WCF
Data
Services致力为数据传,而无是多少存储。你的数码可存放于另外位置:本地的数据库,云端的数据库,外部的web
services,xml文件,等等。无论数额是怎来之,你都得就此同样的不二法门来发表/使用它。

   下面我们尽管使WCF Data
Service将服务器的Windows应用程序日志向外宣布。我们的应用程序可以管日志直接就是写于Windows的日记里,然后经行使WCF
Data Service非常容易的即以日志想别急需之用户公开。WCF Data
Service默认使用的凡Entity Framework,使用Entity Framework参看文章WCF
Data Service
QuickStart,还有一个Reflection
Provider,可以支持就念之数据服务,这个例子就是以身作则使用Reflection
Provider,资料参看MSDN:http://msdn.microsoft.com/en-us/library/dd723653(VS.100).aspx,还好自定义实现一个Provider,参看文章自定义Data
Service
Providers。

率先定义一个Windows日志的实体,类似于WCF的DataContract,这里以的是EDM的映照:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Services.Common;

namespace ReflectionDataServiceDemo
{
    [EntityPropertyMappingAttribute(“Source”,
         SyndicationItemProperty.Title,
         SyndicationTextContentKind.Plaintext, true)]
    [EntityPropertyMapping(“Message”,
        SyndicationItemProperty.Summary,
        SyndicationTextContentKind.Plaintext, true)]
    [EntityPropertyMapping(“TimeGenerated”,
        SyndicationItemProperty.Updated,
        SyndicationTextContentKind.Plaintext, true)]
    [DataServiceKey(“EventID”)]
    public class LogEntry
    {
        public long EventID
        {
            get;
            set;
        }

        public string Category
        {
            get;
            set;
        }

        public string Message
        {
            get;
            set;
        }

        public DateTime TimeGenerated
        {
            get;
            set;
        }

        public string Source
        {
            get;
            set;
        }

    }

}

面使用一个新特点Friendly
feeds
将数据映射到专业ATOM元素,其中DataServiceKey是绝无仅有一个务必的记号,然后使用Reflection
Provider实现一个IQueryable接口的数据源:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Diagnostics;

namespace ReflectionDataServiceDemo
{
    public class LogDataSource
    {
        string source;

        public LogDataSource(string source)
        {
            this.source = source;
        }

        public LogDataSource()
        {
        }

        public IQueryable<LogEntry> LogEntries
        {
            get { return GetEntries().AsQueryable().OrderBy(e =>
e.TimeGenerated); }
        }

        private IEnumerable<LogEntry> GetEntries()
        {
            var applicationLog =
System.Diagnostics.EventLog.GetEventLogs().Where(e => e.Log ==
“Application”)
                .FirstOrDefault();

            var entries = new List<LogEntry>();

            if (applicationLog != null)
            {
                foreach (EventLogEntry entry in
applicationLog.Entries)
                {
                    if (source == null || entry.Source.Equals(source,
StringComparison.InvariantCultureIgnoreCase))
                    {
                        entries.Add(new LogEntry
                        {
                            Category = entry.Category,
                            EventID = entry.InstanceId,
                            Message = entry.Message,
                            TimeGenerated = entry.TimeGenerated,
                            Source = entry.Source,
                        });
                    }
                }
            }

            return entries.OrderByDescending(e => e.TimeGenerated)
                        .Take(200);
        }
    }

}

末补充加一个WCF Data
Service,代码非常之大概,主要的行事便是以上述数据源通过WCF Data
Service发布出去:

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
using System.Configuration;

namespace ReflectionDataServiceDemo
{
    public class LogDataService : DataService<LogDataSource >
    {
        // This method is called only once to initialize service-wide
policies.
        public static void InitializeService(DataServiceConfiguration
config)
        {
            // TODO: set rules to indicate which entity sets and service
operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule(“*”,
EntitySetRights.AllRead);
            config.SetServiceOperationAccessRule(“*”,
ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion =
DataServiceProtocolVersion.V2;
        }

        protected override LogDataSource CreateDataSource()
        {
            string source =
ConfigurationManager.AppSettings[“EventLogSource”];
            if (source == null)
            {
                throw new ApplicationException(“The EventLogSource
appsetting is missing in the configuration file”);
            }

            return new LogDataSource(source);

        }
    }
}

咱俩重新来形容单简单控制高客户端消费是Service,通过Visual
Studio的长服务引用生成服务之客户端代码,还可运用一个插件Open Data
Protocol
Visualizer
查阅服务返回的OData数据数据,这个家伙的获和安好参考VS2010的扩展。可以由此劳动引用的“View
in Diagram”进行查看。

图片 2

客户端的代码也非常简单;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClientDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            LogDataService.LogDataSource logSource = new
LogDataService.LogDataSource(new
Uri(“http://localhost:3399/LogDataService.svc/”));))
            foreach (var item in logSource.LogEntries)
            {
               
Console.WriteLine(string.Format(“来自{0}事件{1},内容{2}”, item.Source,
item.EventID, item.Message));
            }
            Console.Read();
        }
    }
}

 

种类代码可以到此地得到
http://cid-33478a966734670f.skydrive.live.com/self.aspx/.Public/ReflectionDataServiceDemo.zip