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. Oracle连接配置以及实例的备份和恢复

    背景:一个团队项目开发,不可能每个人都架设自己本地的数据库,大多数情况下是统一用服务器上的数据库,这时候就需要进行远程数据库的连接.而且有时候还需要进行数据库搬迁 ,这时候就需要进行数据库的备份和恢复 ...

  2. ios - objective-c runtime之随笔

    今天身体不舒服,还顶着写这篇博客. 举个例子,我们之前在写objective-c代码时,经常用到id这个关键字.那 id 究竟是什么?在objective-c的运行时,这样描述的,它其实是一个结构体( ...

  3. Java多线程--同步函数

    /*需求:银行有一个金库有两个储户分别存300元 每次存100元,存3次 目的:该程序是否有安全问题,如果有,如何解决? 如何找问题(很重要)1.明确哪些代码是多线程运行代码2.明确共享数据3.明确多 ...

  4. 18_高级映射:一对一查询(使用resultMap)

    [简述] 数据库模型和数据等信息与上一篇博文相同. 需求也同上一篇博文. [工程截图] [User.java]POJO package cn.higgin.mybatis.po; import jav ...

  5. CAF(C++ actor framework)使用随笔(send sync_send)(二)

    a). 发完就忘, 就像上面anon_send 以及send #include <iostream> #include "caf/all.hpp" #include & ...

  6. 学习C++ Primer 的个人理解(十二)

    动态内存与智能指针 在C++中, 动态内存用 new来分配空间并返回一个指向该对象的指针 用delete来销毁. 由于手动的对动态内存进行操作容易出现问题.所以新的标准库提供了两种智能指针. 智能指针 ...

  7. Linux启动提示“unexpected inconsistency;RUN fsck MANUALLY”

    问题:在开机启动时,提示“unexpected inconsistency;RUN fsck MANUALLY”进不了系统 解决方法: fsck不仅可以对文件系统进行扫描,还能修正文件系统的一些问题, ...

  8. windows phone 网易云阅读hubtile效果实现

    效果图 曾几何时,刚接触wp的时候做了一个类似的界面,不过是Rectangle实现的,还是一个个摆的..囧啊 现在感觉这种应该是用hubtile实现的,Toolkit(http://silverlig ...

  9. debian 学习记录-2 -账户 -关机

    linux考虑系统安全设定了root账号和user账号 权限较低的user账号下,连关机命令都执行不了…… 用户切换... 用户切换1 命令su(在user账号下,即可开启root账号模式) 用户切换 ...

  10. JSON Date Format/JSON 日期格式方法分享

    我是很懒的,不想多说,所以直接上代码.亲们懂的. <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://w ...