日志是开发系统时的有效工具和常见需求。它不仅可以在程序排错时提供调试信息,还可以记录系统运行的日常状况,以供需要时查询或集中起来分析。在一些主要的编程语言如Java中,都有不少日志框架可供选择。在LotusNotes里,在文档、代理、数据库和系统级别Notes本身记录和保留了很多信息,再加上Notes数据库功能和日志载体格式的限制,通用的日志程序和框架不发达。不过在OpenNtf.Org网站上,也至少有两个项目是用于日志的。一是广受好评的OpenLog,最大的特色就是只有一行调用函数就可以得到外观不错信息丰富的错误记录。另一个是鲜有人注意的Log4Dom特点是(从名称上也可以看出来)仿造Log4J的思路,创建了一套自定义类以记录日志。前者虽然方便,但是从笔者的角度看,记录的信息有些累赘,而且表单和视图都有特定的外观风格,不易整合进整个系统。如果是要记录错误信息,笔者觉得使用34. LotusScript中的错误处理程序一文中的代码就足够了。后者的思路和风格笔者却很喜欢。虽然它也有不少缺点,比如一味模仿Log4J,建立的几个日志载体类有些牵强,调用过程也不方便,并且重要的是还有几个bug影响使用。于是笔者对它作了一定的调整和修改,它遂变成开发中不可少的称手工具。
日志视图:
单个日志文档:
记录了错误信息的日志文档:
在一个函数中使用Log4Dom记录错误信息到日志的样例如下:
Private Function SendUrgentMail(doc As NotesDocument)
Dim s As New NotesSession
Dim db As NotesDatabase
Set db=s.Currentdatabase
Dim logger As log4dom
Set logger = GetLogger(Nothing)
On Error GoTo ErrorHandler Dim sendTo As String
sendTo=GetMail(doc.PersonInCharge(0))
logger.debug("Sent an urgent PO to: " & sendTo)
If sendTo="" Then
Print "The mail of the current handler of the PO is not found."
GoTo ExitFunction
End If
Dim body As String, subject As String
body=GetMailBody(doc)
subject="An Urgent Purchasing Order Of No. " & doc.No(0) & " Is Appending For Your Handling."
Call SendHTMLMail(sendTo, subject, body)
'mark the documents
Call doc.ReplaceItemValue("SentSummary", "Y") ExitFunction:
Call logger.Close()
Exit Function
ErrorHandler:
Call logger.HandleError()
GoTo ExitFunction
End Function
开发中更多用到日志的是定时运行的代理,为此我们可以几个自定义类,在其中可以方便地直接使用一个作为对象字段的日志对象,而无需像上面那样专门定义和初始化日志实例。
Public Class UseLog
Private logger As log4Dom %REM
Sub New
Description: Comments for Sub
%END REM
Sub New()
Set logger=GetLogger(Nothing)
End Sub 'close the logger
Sub Delete()
Call logger.Close()
End Sub End Class Public Class AgentWithLog As UseLog
Private s As NotesSession
Private db As NotesDatabase %REM
Sub New
Description: Comments for Sub
%END REM
Sub New()
Set s=New NotesSession
Set db=s.CurrentDatabase
End Sub
End Class
下面是一个使用上面的UseLog或AgentWithLog类的样例。只保留了使用日志的部分代码。代码较长,只需注意调用日志对象记录信息和错误的语句。本文上面图片中的日志大部分就是由这个代理产生的。
Private Class Reminder As UseLog
Private s As NotesSession
Private db As NotesDatabase
Private view As NotesView
Private detailCols As Dictionary
Private detailHeads As Variant
Private detailFields As Variant Sub New()
On Error GoTo ErrorHandler
Set s=New NotesSession
Set db=s.Currentdatabase
Set view=db.Getview(VIEW_PO_BY_STATUS)
view.Autoupdate=False
Set me.detailCols=New Dictionary
With detailCols
Call .Add("Description", "Title")
Call .Add("Amount", "Amt_1")
Call .Add("Sub Expense Account", "expItem")
Call .Add("Employee", "Employee")
Call .Add("Office", "Office")
Call .Add("Department", "Dept")
End With
me.detailFields=me.detailCols.GetValues()
me.detailHeads=me.detailCols.GetKeys()
Exit Sub ErrorHandler:
Call logger.HandleError()
Exit Sub
End Sub Sub Delete()
view.Autoupdate=true
End Sub Private Function Notify(status As String, handler As String )
On Error GoTo ErrorHandler Dim keys(1) As String
Dim sendTo As Variant keys(0)=status 'status
keys(1)=handler 'handler
sendTo=GetCustomMail(keys(1), "OA\CTHR.nsf", "bySCRO", "Staff_EMail")
If sendTo="" Then
logger.info(keys(1) & "'s mail not found.")
Else
Dim vec As NotesViewEntryCollection
Set vec=view.Getallentriesbykey(keys, True)
Dim body As String, subject As String, copyTo As Variant
body=GetMailBody(vec)
subject=vec.Count & " Expenses Of Status " & keys(0) & " Are Pending For Your Handling"
Select Case keys(0)
Case "4.2 Rejected After Final Review"
'inform all the users Brad rejected the PO
copyTo=GetCustomMail(vec.Getfirstentry().Document.FlowReaders, _
"OA\CTHR.nsf", "bySCRO", "Staff_EMail")
logger.info("Copy to: " & Join(copyTo, ","))
Case Else
copyTo=""
End Select Call CCHTMLMail(sendTo, copyTo, "", subject, body)
If IsArray(sendTo) Then
sendTo=Join(sendTo, ", ")
End If
logger.info("Sent Expense Summary of '" & keys(0) & "' to " & sendTo)
'mark the documents
'Call dc.Stampall("SentSummary", "Y")
End If
Exit Function ErrorHandler:
Call logger.HandleError()
Exit Function
End Function End Class
下一片文章里,我们来详细看看这个背后的Log4Dom。
48. 面向对象的LotusScript(十四)之Log4Dom上的更多相关文章
-
java 面向对象编程--第十四章 多线程编程
1. 多任务处理有两种类型:基于进程和基于线程. 2. 进程是指一种“自包容”的运行程序,由操作系统直接管理,直接运行,有自己的地址空间,每个进程一开启都会消耗内存. 3. 线程是进程内部单一的 ...
-
java 面向对象(三十四):泛型三 自定义泛型类、泛型接口、泛型方法
1.举例: [Order.java] public class Order<T> { String orderName; int orderId; //类的内部结构就可以使用类的泛型 T ...
-
java 面向对象(二十四):interface:接口
interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...
-
java web学习总结(二十四) -------------------Servlet文件上传和下载的实现
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
-
Spring MVC 使用介绍(十四)文件上传下载
一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...
-
【php增删改查实例】第二十四节 - 文件上传在项目中的具体应用
文件上传在项目中,一般有两个用武之地,分别为设置用户的头像和上传附件.本节我们演示如果进行用户头像的上传. 因为一个用户单独并且唯一对应了一个头像,是一对一的关系,所以我们需要去给tm_users表添 ...
-
python接口自动化测试三十四:github上某接口测试平台及配置
TeserHome地址:https://testerhome.com/opensource_projects/60前端:https://github.com/pencil1/ApiTestWeb 实现 ...
-
201671030113 李星宇 实验十四 团队项目评审&;课程学习总结
项目 内容 所属课程 [所属课程(https://www.cnblogs.com/nwnu-daizh/) 作业要求 作业要求 课程学习目标 (1)掌握软件项目评审会流程:(2)反思总结课程学习内容 ...
-
linux基础-第十四单元 Linux网络原理及基础设置
第十四单元 Linux网络原理及基础设置 三种网卡模式图 使用ifconfig命令来维护网络 ifconfig命令的功能 ifconfig命令的用法举例 使用ifup和ifdown命令启动和停止网卡 ...
随机推荐
-
提取ecshop的mysql类
在下一篇文章中,我还将介绍如何完善ecshop的mysql类,使用ecshop的数据库前缀 下载ecshop后,解压缩,进入目录upload/includes,复制里面的cls_mysql.php放进 ...
-
vue2.0自定义指令
前面一片文章说了vue2.0过滤器,其实自定义指令跟过滤器非常相似,单就定义方式而言,其与过滤器完全一致,分为局部指令,和全局指令.不过就是filter改为directive的区别. 过滤器一般用于对 ...
-
背水一战 Windows 10 (45) - 控件(图标类): IconElement, SymbolIcon, FontIcon, PathIcon, BitmapIcon
[源码下载] 背水一战 Windows 10 (45) - 控件(图标类): IconElement, SymbolIcon, FontIcon, PathIcon, BitmapIcon 作者:we ...
-
树莓派UFW防火墙简单设置
ufw是一个主机端的iptables类防火墙配置工具,比较容易上手.如果你有一台暴露在外网的树莓派,则可通过这个简单的配置提升安全性. 安装方法 sudo apt-get install ufw 当然 ...
-
Docker中执行Shell出现乱码
问题描述 最近遇到一个问题: 执行命令 docker exec f4af9b sh -c 'bash /tmp/build.sh' 命令在docker中执行shell,会出现中文乱码的问题.但是在do ...
-
M3截止阶段小结
python知识点总结1.copy模块中深浅拷贝copy() deepcopy()2.__new__ 方法参数 def __new__(cls, *args, **kwargs): ...
-
C++复习9.面向对象编程
C++ 面向对象编程概述 20131001 一些基本概念:封装.继承.组合.虚函数.抽象基类.动态绑定.多态性等等 1.一个笑话:如果坐在后排聊天的同学能够像中间打牌的同学那样安静的话,那么就不会影响 ...
-
牛顿迭代,多项式求逆,除法,开方,exp,ln,求幂
牛顿迭代 若 \[G(F_0(x))\equiv 0(mod\ x^{2^t})\] 牛顿迭代 \[F(x)\equiv F_0(x)-\frac{G(F_0(x))}{G'(F_0(x))}(mod ...
-
安装loadrunner时出现”命令行选项语法错误键入命令 \?获得帮助“的解决方法
安装LR11 时,安装Microsoft Visual c++2005 sp1运行时组件,就会提示命令行选项语法错误,键入“命令/?”可获取帮肋信息1.进入loadrunner-11\Addition ...
-
Spring启动后获取所有拥有特定注解的Bean,注解的属性值
最近项目中遇到一个业务场景,就是在Spring容器启动后获取所有的Bean中实现了一个特定接口的对象,第一个想到的是ApplicationContextAware,在setApplicationCon ...