12.7.1 创建日志记录的计算

这个计算将产生一个值,并能够将消息写入到本地日志记录缓冲区。这样,计算的结果将成为一个值,和包含消息的字符串列表。同样,我们使用只有一个识别器的差别联合,表示这个类型:

type Logging<‘T> =

| Log of ‘T * list<string>

这个类型非常类似于我们先前讨论的 ValueWrapper <‘a> 示例,只是加上了一个 F# 列表,表示写到日志的消息。现在,我们已有了类型,就可以实现计算生成器了。通常,我们需要实现 Bind 和 Return 成员;此外,还会实现一个新成员Zero,能够写不返回任何值的计算。后面,我们将会看到它是如何使用的。

清单 12.23 是这个生成器的实现。最重要的是Bind 成员,它把原始值的日志消息,和由计算的其余部分(是给 Bind 成员参数的函数)生成的值,连接起来。

清单 12.23 增加了日志功能的计算生成器 (F#)

type LoggingBuilder() =

member x.Bind(Log(value, logs1), f)=     [1]

let (Log(newValue,logs2)) = f(value)      [2]

Log(newValue, logs1 @logs2)     [3]

member x.Return(value) =

Log(value, [])     <-- 增加了空日志值

member x.Zero() =

Log((), [])     <-- 不返回空日志值

let log = new LoggingBuilder()

与其他例子一样,最困难的部分是实现 Bind 成员。我们的日志记录类型遵循所有正常的步骤,包括option 和 ValueWrapper 类型,和省略的第三步:

1、我们要提取值。因为使用只有一种情况的差别联合,在成员的参数列表中[1],可以使用模式匹配;

2、如果有值需要计算,就调用计算的其余部分。在清单 12.23 中,总是有值,因此,可以运行给定的函数[2]。我们没有立即返回结果,而是先分解,得到在执行过程中产生的新的值和日志消息。

3、我们已经收集了两个日志消息的缓冲,所以,需要打包这个新的值,并为它添加新的日志状态。若要创建新状态,我们把原始的消息列表,和在调用计算的其余部分时生成的新列表连接起来[3]。使用列表连接运算符(@)。

Return 和 Zero 成员很简单。Return 需要把实际值打包到Logging<‘T> 类型中,Zero 表示不携带任何值的计算(即,返回 unit)。在这两种情况下,我们都将创建新的计算值,因此,基本操作返回空的日志记录缓冲。所有的日志消息将以其它方式产生,并在Bind 成员中追加。如果你看到了到目前为止我们写的代码,没有任何办法,可以创建非空的日志!因此,我们需要创建一个额外的基本操作,以创建包含日志消息的计算值。可以写成一个简单的函数:

> let logMessage(s) =

Log((), [s])

val logMessage : string ->Logging<unit>

这个函数创建一个包含 unit 值的计算值,更重要的是,还包含在日志记录的缓冲中的消息,因此,如果我们使用 Bind,把它与另外的计算组合起来,就能得到写到日志中的计算。现在,我们终于可以写代码,使用新创建的日志记录计算。

时间: 2024-10-25 04:34:19

12.7.1 创建日志记录的计算的相关文章

12.7.2 创建日志记录计算

清单 12.24 首先实现两个辅助函数,用于读写控制台,且两者还会把消息写入日志,所以,它们将括在 log 计算块中.为了显示如何组合非标准计算,我们在第三个函数中,使用了两个函数.在前面的示例中,我们使用 let! 基本操作,在清单 12.24 还引入了 do!. 清单 12.24 使用计算表达式的日志 (F# Interactive) > let write(s) = log {    [1] <-- 写字符串到控制台和日志 do!logMessage("writing: &qu

PHP创建日志记录(已封装)

1 <?php 2 3 class Logs{ 4 private $_filepath; //文件路径 5 private $_filename; //文件名 6 private $_filehandle; //文件引擎 7 8 9 public function Logs($dir = null,$filename = null){ 10 11 $this->_filepath = empty($dir) ? '': $dir; 12 $this->_filename = empty

springmvc+log4j操作日志记录,详细配置

没有接触过的,先了解一下:log4j教程 部分内容来:log4j教程 感谢! 需要导入包: log包:log4j-12.17.jar 第一步:web.xml配置 <!-- log4j配置,文件路径,因为是跟随项目启动 --> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.xml</param-value>

12.7 给计算增加日志记录

日志通常可以使用全局可变状态实现.然而,如果我们想要避免使用全局可变状态,并保持程序的纯函数性,那又该如何呢?我们有一个选择,就是把日志记录器的状态作为额外的参数值,传递我们要调用的每个函数.实现可能非常困难(想象一下,如果我们决定将另一个参数添加到这个状态中!). 要解决这个问题,我们可以创建自定义计算类型,启用了日志记录,把日志记录器的状态隐藏在计算类型内.这类似于在无任何副作用的纯函数式语言中, Haskell 使用的技术,嵌入处理状态(比如,文件系统).我们要实现的示例依赖于这样的事实,

log4j教程 12、日志记录到数据库

log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 bufferSize 设置缓冲区的大小.默认大小为1 driver 设置驱动程序类为指定的字符串.如果没有指定驱动程序类,默认为sun.jdbc.odbc.JdbcOdbcDriver layout 设置要使用的布局.默认布局是org.apache.log4j.PatternLayout password

C# 创建自己的日志记录类 源码

调试及发布程序时,经常需要将一些信息输出保存,这里写了一个自己的日志记录类,记录信息更方便了.需要的话还可以进行更多的扩展,比如记录异常信息等. using System; using System.IO; namespace WindowsFormsApplication1 { public static class LogerHelper { #region 创建日志 ///-----------------------------------------------------------

Linux下定时切割nginx日志并删除指定天数前的日志记录

nginx的log日志分为access.log和error.log:其中access.log 记录了哪些用户.哪些页面以及用户浏览器.ip和其他的访问信息:error.log则是记录服务器错误日志. error.log日志的形式如下: 201.158.69.116 - - [03/Jan/2013:21:17:20 -0600] fwf[-] tip[-] 127.0.0.1:9000 0.007 0.007 MX pythontab.com GET /html/test.html HTTP/1

Linux服务器上创建日志服务器和FTP服务器

参考地址: http://www.111cn.net/sys/CentOS/81133.htm https://www.cnblogs.com/laoxiajiadeyun/p/9943742.html https://blog.51cto.com/liqingbiao/2119953 https://www.cnblogs.com/hasayaki/archive/2013/01/24/2874889.html 在 Linux 上配置一个 syslog 服务器 syslog服务器可以用作一个网

转:使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)

http://www.cnblogs.com/kyo-yo/archive/2010/06/11/use-log4net-to-log-exception.html 在前端时间开发的时候由于需要将异常保存到数据库中,所以就到网上搜了下专门的日志记录工具,一搜果然很多,比如:log4net,NLog,EntLib Logging等等,但是还是log4net名气最大,所以就下载下来试用了一番,果然很方便,其涵盖了所有常用的日志记录方式具体的可以看下表: AdoNetAppender 将日志记录到数据