Log4Dom是模仿Log4J的思想建立的。Log4J能够向多种记录媒介以统一的格式写入各种级别的日志信息(包括错误、调试和信息等),还可以籍配置文件在运行时方便地修改记入日志的级别。Log4Dom提供了类似的功能。现在我们就来看看它的各部分元素和代码。

1.      记录日志的文档所用的表单

2.      用于配置日志级别的表单

3.      日志文档视图

第一列按创建日期分类,第二列是文档序号,第三列是创建时间,最后一列是日志名称。还有一个操作可以编辑配置文档。

4.      日志类代码

'*version 1.2-18th March 2008
'*added Log4Dom profile,
'*simplified the usage and renamed some methods,
'*deleted unnecessary log document size check
'*added several features e.g. logging generated error message, expanding the log message
'*argument to variant
'*corrected several bugs
'*@author Starrow Pan
'/**
'* class for the domino implementation of a logger in a similar format
'* as log4J (http://jakarta.apache.org/log5j/
'* @author tony.palmer@ing.com.au
'* @version 1.0 - 4th November 2003
'*/
Private Const CUSTOM_ERR=10000
Private Const CUSTOM_ERROR="CUSTOM ERROR: " ' debugging levels 0 - 5 system, 6 - 10 custom
Const LEVEL_DEBUG = 5
Const LEVEL_DEBUG_STRING = "DEBUG"
Const LEVEL_INFO = 4
Const LEVEL_INFO_STRING="INFO"
Const LEVEL_WARN = 3
Const LEVEL_WARN_STRING = "WARN"
Const LEVEL_ERROR = 2
Const LEVEL_ERROR_STRING = "ERROR"
Const LEVEL_FATAL = 1
Const LEVEL_FATAL_STRING = "FATAL"
Const LEVEL_NONE = 0 ' destination types
Const DEST_TYPE_DB = 0 '/ notes database
Const DEST_TYPE_FILE = 1 '/ text file
Const DEST_TYPE_STATUS = 2 '/ notes status bar
Const DEST_TYPE_PROMPT = 3 '/ message box prompts Class Log4Dom
public logLevel As Integer
public module As String 'module 'the Log Destination, set as a variant then depending on the log type,
'set as either a LogDB, logNotesFile, logStatus or logPrompt
Private logFile As Variant Private m_sess As NotesSession
Private m_curdb As NotesDatabase 'current database
Private m_profile As NotesDocument 'Log4Dom profile document
public logName As String 'log name from the profile Sub New ()
Set m_sess=New NotesSession
logLevel = LEVEL_DEBUG
End Sub %REM
Add a log destination.
As the de facto only used log destination is Notes DB,
I didn't handle the case of multiple log destinations of different types.
%END REM
Public Function AddLogFile(file As Variant)
Set logFile = file If TypeName(file)="LOGDB" then
'read parameter from Log4Dom profile by starrow
Set m_curdb=m_sess.CurrentDatabase
Set m_profile=m_curdb.GetProfileDocument("Log4DomProfile")
If Not m_profile Is Nothing Then
If m_profile.GetItemValue("LogLevel")(0)><"" then
logLevel=m_profile.GetItemValue("LogLevel")(0)
End if
logName=m_profile.GetItemValue("LogName")(0)
End If
'if no parameter provided, try the agent name
If logName="" Then
If Not m_sess.CurrentAgent Is Nothing Then
logName=m_sess.CurrentAgent.Name
End If
End If logFile.LogName=logName
End if
End Function 'logging at the different levels, INFO, WARN etc
Public Function info(message As variant) As Integer
info = WriteLog(LEVEL_INFO, message)
End Function Public Function warn(message As variant) As Integer
warn = WriteLog(LEVEL_WARN, message)
End Function Public Function debug(message As variant) As Integer
debug = WriteLog(LEVEL_DEBUG, message)
End Function Public Function LogError(message As variant) As Integer 'can't use error as its a reserved word
If message="" Then
'LSI_THREAD_CALLMODULE=11, LSI_THREAD_CALLPROC=10
message = GetThreadInfo(11) & ">" & GetThreadInfo(10) & ": " & _
"Error(" & Err() & "): " & Error() & " at line "& Erl()
End If
LogError = WriteLog(LEVEL_ERROR, message)
End Function Public Function fatal(message As variant) As Integer
fatal = WriteLog(LEVEL_FATAL, message)
End Function 'user level logging, for specific level logging
'@param level integer - the level 10 is the most detail, 1 the lowest level
Public Function WriteLog(level As Integer, message As variant) As Integer
Dim theDate As String
Dim theLevel As String
Dim theMessage As String
theDate = Cstr(Now)
theLevel = "["+GetLevelString(level)+"] "
theMessage = theDate+" "+theLevel+" "+module+" - "+message
' check that logging is turned on for this level
' otherwise there is no need to log
If level <= logLevel Then
Call logFile.writelog(theMessage)
End If
End Function 'closes the log, saves notes doc or closes file
Public Function Close
logFile.close
End Function 'convert from level numbers into string
Private Function GetLevelString(level As Integer) As String
Select Case level
Case LEVEL_INFO : GetLevelString = LEVEL_INFO_STRING
Case LEVEL_DEBUG : GetLevelString = LEVEL_DEBUG_STRING
Case LEVEL_WARN : GetLevelString = LEVEL_WARN_STRING
Case LEVEL_ERROR : GetLevelString = LEVEL_ERROR_STRING
Case LEVEL_FATAL : GetLevelString = LEVEL_FATAL_STRING
Case Else : GetLevelString = "LEVEL "+Cstr(level)
End Select
End Function End Class '/**
'* Set Log destination as a domino database
'*/
Class LogDB
Private m_sess As NotesSession
Private m_dbLog As NotesDatabase 'nsf if destination is db
Private m_docLog As NotesDocument 'document that the log gets appended to
Private m_rtitem As NotesRichTextItem 'rtf
public logName As String Sub New(db As NotesDatabase)
Set m_sess=New NotesSession
If db Is Nothing Then
Set m_dbLog = m_sess.currentdatabase
Else
Set m_dbLog = db
If m_dbLog.isOpen = False Then
Error CUSTOM_ERR, CUSTOM_ERROR & "Could not open the log Database."
End If
End If
End Sub 'get the log document as some calling program may need access it e.g. mail it.
Public Property Get LogDocument As NotesDocument
Set LogDocument=m_docLog
End Property '/**
'* method for logging to a notes document
'*/
Public Function writeLog(message As String) As Integer
If m_docLog Is Nothing Then
' create a new log document
Set m_docLog = m_dbLog.createDocument
Call m_docLog.ReplaceItemValue("LogName",logName)
If m_sess.IsOnServer Then
Call m_docLog.ReplaceItemValue("ScriptRunOn","Server")
Else
Call m_docLog.ReplaceItemValue("ScriptRunOn","Workstation")
End If
Set m_rtitem = New NotesRichTextItem(m_docLog, "logBody")
End If
'currently each log line is in one paragraph, no limits will be violated
m_rtitem.appendtext(message)
m_rtitem.addnewline(1) writeLog= True
End Function '/**
'* closes the log, saves notes doc
'*/
Public Function Close
If Not(m_docLog Is Nothing) Then
m_docLog.Form="log"
Call m_docLog.Save(True,True)
End If
End Function
End Class 'Get a logger instance that writes to the specified db.
Public Function GetLogger(db As NotesDatabase) As log4Dom
Dim logger As log4dom
Set logger = New log4dom()
Dim logFile As New LogDB(db)
Call logger.AddLogFile(logFile)
Set GetLogger=logger
End Function

上述代码的各个方法都有注释。使用的时候像上一篇文章里所示样例一样,只需初始化一个logger实例并添加目标数据库(若为当前数据库,就传入Nothing),之后就可以调用Info()、Debug()、LogError()等各种方法写入日志。传入LogError()方法的如果是空字符串,它就会试图记录最近发生的错误的详细信息,因此可以用作处理错误的语句。最后要调用Close()方法,记录日志的文档才会被保存。

原来版本所具的其他日志目标媒介类,实际上都极少用到。Notes文档和视图的现成功能使其很适宜用来记录和查询日志。文本文件比起来不那么方便,而要写到状态栏或者用对话框显示直接用LotusScript对应的语句即可。

49. 面向对象的LotusScript(十五)之Log4Dom下的更多相关文章

  1. java 面向对象(二十五):内部类:类的第五个成员

    内部类:类的第五个成员 1.定义: Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类.2.内部类的分类:成员内部类(静态.非静态 ) vs 局部内部类(方法内.代码块内.构 ...

  2. java 面向对象(三十五):泛型在继承上的体现

    泛型在继承上的体现: /* 1. 泛型在继承方面的体现 虽然类A是类B的父类,但是G<A> 和G<B>二者不具备子父类关系,二者是并列关系. 补充:类A是类B的父类,A< ...

  3. How tomcat works 读书笔记十五 Digester库 下

    在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的co ...

  4. 性能测试十五:liunx下搭建(tomcat+项目+jmete命令行)

    单机 准备工作: 1.压力机安装并配置好JDK,输入java和javac验证环境变量 2.上传jmeter到liunx下: 准备好jmeter的压缩包 在第三方工具中对linux文件上传下载(需先装好 ...

  5. 马凯军201771010116《面向对象与程序设计Java》第十五周学习知识总结

    实验十五  GUI编程练习与应用程序部署 一.知识学习部分 清单文件 每个JAR文件中包含一个用于描述归档特征的清单文件(manifest).清单文件被命名为MANIFEST.MF,它位于JAR文件的 ...

  6. “全栈2019”Java第三十五章:面向对象

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. 201271050130-滕江南-《面向对象程序设计(java)》第十五周学习总结

    201271050130-滕江南-<面向对象程序设计(java)>第十五周学习总结 博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.c ...

  8. 201871010111-刘佳华《面向对象程序设计(java)》第十五周学习总结

    201871010111-刘佳华<面向对象程序设计(java)>第十五周学习总结 实验十三  Swing图形界面组件(二) 实验时间 2019-12-6 第一部分:理论知识总结 5> ...

  9. 201871010123-吴丽丽《面向对象程序设计(Java)》第十五周学习总结

    201871010123-吴丽丽<面向对象程序设计(Java)>第十五周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

随机推荐

  1. 【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记1 IOS8概述

    首先感谢网易公开课和SwiftV课堂的朋友们辛苦翻译,这个系列是我学习斯坦福IOS8公开课的个人心得体会和笔记,希望能给大家带来启发. 首先我们要知道IOS系统中的结构情况,从贴近硬件的底层到贴近用户 ...

  2. ios 视频音乐播放

    IOS开发小技巧(视频和音乐播放).IOS视频播放代码(添加MediaPlayer.framework和#import) -(void)playMovie:(NSString *)fileName{ ...

  3. windows server 2003 负载平衡的详细设置步骤(转载)

    声明:本文为转载. 当把一台服务器(包括Web服务器.FTP服务器或者流媒体服务器等等)放入网络中之后,随着客户端数量的不断增加,人们往往需要功能更强大.处理速度更快的服务器.为了解决这个问题,如果将 ...

  4. Generate GUID using vbscript

    在 .msi 中 的 Component table,查看 ComponentId 列,是一个16进制数的字符串, 用 InstallShield IDE 添加一个 component ,Compon ...

  5. [Effective Objective-C 读书笔记] 第1章 几条基本写法 (2~5条)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3575599.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  6. 九度OJ 城际公路网 -- 图论

    题目地址:http://ac.jobdu.com/problem.php?pid=1343 题目描述: 为了加快城市之间的通行和物资流动速度,A国政府决定在其境内的N个大中型城市之间,增加修建K条公路 ...

  7. 九度OJ 1056--最大公约数 1439--Least Common Multiple 【辗转相除法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1056 题目描述: 输入两个正整数,求其最大公约数. 输入: 测试数据有多组,每组输入两个正整数. 输出: 对于每组 ...

  8. 微软自带iscsi客户端对iqn的要求

    节点名称:Microsoft iSCSI 发起程序严格遵守为 iSCSI 节点名称指定的规则.这些规则也适用于 Microsoft iSCSI 发起程序节点名称以及发现的任何目标节点名称.构建 iSC ...

  9. C#基础(五)——类中私有构造函数作用

    如果类成员有private修饰符,就不允许在类范围以外访问这个类成员.对类构造函数应用private修饰符时,则禁止外部类创建该类的实例.尽管看上去有些不好理解(既然不能实例化,那么这个类还有什么用处 ...

  10. js实现浏览器兼容复制功能

    经常看到这样一种效果:就是单击一个按钮,就将某个区域内的内容,复制到了剪切板中.其实这个功能实现起来也不难,核心就是用到了window子对象clipboardData的一个方法:setData()语法 ...