RTP 记录 log 该机制
我们 RCV 在这里,经常跑concurrent request RTP: Receiving Transaction Processor, 它主要是用来处理 RCV_TRANSACTIONS_INTERFACE 内的数据.
这个 concurrent program 里面包括很多文件, 比較重要的有:
ident RVCTP
RVCTP:
$Header: rvctp.oc 120.0.12000000.1 2007/01/16 23:53:49 appldev ship $
$Header: rvtbm.lpc 120.13.12010000.10 2013/03/15 02:51:16 zhlee ship $
$Header: rvtpt.lpc 120.28.12010000.33 2013/07/15 07:12:37 smai ship $
$Header: rvtvq.lpc 120.8.12010000.17 2013/04/03 11:40:30 wayin ship $
$Header: rvtuq.lpc 120.9.12000000.7 2009/07/07 09:47:49 YUZZHANG01 ship $
$Header: pouer.lpc 120.2 2006/06/14 07:57:02 arudas noship $
$Header: rvtlo.lpc 120.1.12010000.7 2013/01/05 16:02:14 gke ship $
$Header: rvtoc.lpc 120.1.12010000.5 2013/03/28 22:38:31 vthevark ship $
$Header: rvtpa.lc 120.6.12010000.3 2009/07/07 08:58:22 ksivasa ship $
$Header: rvtpd.lc 120.1.12010000.3 2009/07/07 09:03:17 ksivasa ship $
$Header: rvtsh.lpc 120.10.12010000.3 2009/03/06 22:09:40 vthevark ship $
$Header: rvtth.lpc 120.29.12010000.9 2012/05/30 15:50:03 gke ship $
$Header: rvtvt.lpc 120.9.12010000.10 2013/03/28 18:19:11 vthevark ship $
$Header: rvsco.lpc 120.4.12010000.12 2012/09/27 23:10:24 vthevark ship $
$Header: rvsrv.lpc 120.4.12010000.16 2013/02/04 07:34:37 zhizheng ship $
$Header: rvsit.lpc 120.5.12010000.6 2013/02/04 07:26:30 zhizheng ship $
$Header: rvsdl.lpc 120.5.12010000.17 2011/11/28 05:19:19 xiameng ship $
$Header: rvssh.lpc 120.2.12010000.3 2009/07/07 09:56:26 ksivasa ship $
$Header: rvsut.lpc 120.3.12010000.14 2012/05/28 04:53:57 gke ship $
$Header: rvtcl.lpc 120.6.12010000.3 2009/07/07 09:15:25 ksivasa ship $
$Header: rvtii.lpc 120.19.12010000.27 2013/08/14 09:58:23 gke ship $
$Header: rvtls.lpc 120.7.12010000.14 2012/01/30 12:31:22 ksivasa ship $
$Header: rvtoo.lpc 120.3.12010000.3 2009/07/07 09:08:40 ksivasa ship $
$Header: rvsrq.lpc 120.5.12010000.3 2009/07/07 09:53:56 ksivasa ship $
$Header: rvspo.lpc 120.3.12010000.3 2009/07/07 09:53:12 ksivasa ship $
这些文件是在 RTP log 里面常常见到的. 这里我们主要看看, 在这些文件里是用如何的机制写 log 的.
首先, 要在要写日志的函数里面声明一个变量:
text strbuf[BUFLEN+1];
然后用以下的语句:
strcpy((char *)strbuf,"");
sprintf((char *)strbuf,"RVTUQ:370 req_line_id %ld\n", (long)req_line_id);
Debug(strbuf,TRUE,TRUE);
第一句把 strbuf 清空, 然后把后面的字符串和整型数写入 strbuf, 第三句 Debug 把 strbuf 写入日志. Debug 后面有两个參数:
#define Debug(message,check_sql_error,no_rows_is_error)
第二个參数 check_sql_error 表示 假设希望检查 SQL error, 就设为 TRUE, 否则设为 FALSE. no_rows_is_error 表示 是不是把 NO_DATA_FOUND 当做一个 error. 假设是, 设为TRUE.
Concurrent Request 里面的文件都是 .c 的代码, 假设里面要写SQL, 就要写一句:
EXEC SQL
然后以下写上 SQL. 这句 SQL 有可能会出错, 这时须要一个方法把错误消息写到 log 里面去. 比方:
EXEC SQL
select transaction_id,
unit_of_measure
into :parent_trx_id,
:rec_uom
from rcv_transactions
where transaction_type in ('RECEIVE','MATCH')
start with transaction_id = :p_trx_id
connect by transaction_id = prior parent_transaction_id;
为了捕获这句SQL 可能发生的错误, 我们在这句后面写一句:
pouersql("RVTUQ", "134", FALSE )
pouersql() 这个函数是在 pouer.lpc 文件 (po user error) 中定义的, 假设上面的SQL 发生了错误, 那么就会把 error message 写入 message stack. 而且返回 true.
这里面有三个參数, routine, location, no_rows_is_err.
routine 表示SQL 错误发生的文件名称, 上面的样例中是 RVTUQ.
location 表示SQL 错误发生的位置, 上面的样例中是 134. 这样我们看到日志里面的这个位置就非常easy定位到这句SQL.
no_rows_is_err 表示 是不是把 NO_DATA_FOUND 当做 error 来处理. 上面的样例中我们没有当做 error.
在 pouersql 这个函数的内部, 会去sqlca 里面提取 sqlcode. sqlca 全称是: sql communications area, 是一个用来记录SQL 运行信息的地方. 每次运行一个SQL 都会返回 sqlcode. 假设sqlcode = 0, 那么表示没有错误. 假设 sqlcode > 0, 表示有exception, 假设 sqlcode < 0, 表示发生 error, 要rollback. 我们平时接触的error 都是小于0 的, 可是 NO_DATA_FOUND
是 大于0 的, 代码 1403. pousersql() 函数会去 sqlca 里面提取 sqlcode, 然后推断是否 sqlcode < 0 还是 sqlcode > 0, 假设推断小于0, 那么才把错误消息写入 message stack. 假设大于0, 而且參数里面 no_rows_is_err 设为 TRUE, 那么也会写如message stack.
每次运行一次 SQL 就会更新一次 sqlca, 所以这个结构仅仅记录近期一次运行SQL 的信息 . 错误消息是记录在sqlca.sqlerrm.sqlerrmc 里面的. 所以会把这个里面的字符串写入message stack. 可是sqlerrmc 最多仅仅能记录70 个字符, 所以假设错误消息非常长的话, 就会被截断.
上面的SQL 错误发生的话, pouersql () 返回值为 TRUE. 那么在调用这个函数的地方, 比方 rvtpt.lpc 文件里, 就会捕捉到这个返回值, 推断返回值之后确定发生error 了, 就会调用:
pouertrace( "RVTUQ", "000", "rvtuqdebitmemo()" )
pouertrace () 这个函数也是在pouer.lpc 文件里定义的, 这个函数的返回值总是 false. 它的主要作用也是把错误消息写入 message stack. 三个參数分别为:
file: 表示错误发生的文件
location: 表示错误的位置
subroutine: 表示错误发生的函数.
上面我们提到, sqlerrmc 仅仅能保存70 个字符. 假设错误消息多余70 个字符, 想要得到全部的错误消息的话, 就须要用 sqlglm() 函数. 在使用这个函数之前, 我们要确保 sqlcode < 0, 否则取出来的错误消息是前面的SQL 的消息.
if (pouersql("RVTUQ","019",TRUE))
{
char msg[510];
size_t buf_len, msg_len;
buf_len = sizeof (msg);
sqlglm(msg, &buf_len, &msg_len);
strcpy((char *)strbuf,"");
sprintf((char *)strbuf,"RVTUQ:001 YU SQL ERROR %s \n", (text *) msg);
Debug(strbuf,TRUE,TRUE);
return( FALSE );
}
sqlglm() 函数把错误消息写入 msg, 然后仅仅要把 msg 用 Debug() 函数写入日志就能够了. sqlglm() 函数对字数也有限制, 最大为512 个字符. 相比 sqlerrmc 的70 个字符多非常多了.
版权声明:本文博客原创文章,博客,未经同意,不得转载。
RTP 记录 log 该机制的更多相关文章
- 简单搭建syslog-ng server记录log
### 简单搭建syslog-ng server记录log 安装syslog-ng apt-get install syslog-ng 安装syslog-ng 配置syslog-ng vim /etc ...
- 基于Java+Selenium的WebUI自动化测试框架(三)------记录LOG
在有了Position类和接口类之后,我们是不是立刻就要着手开始写实现类了呢?按照一般的顺序是这样.但是,我们这里先停一下.原因有二: 1)既然是写一个框架,我们希望总体的功能上是全面的.实现类中,我 ...
- C# 添加Log文件、记录Log
其实在平时的开发过程中都是不怎么写log的,觉得在debug中能看得一清二楚.同事小姐姐前辈,一直就我不写log进行批判,但是我从来不改,哈哈.也算是遇到报应了,在最近一个工程里,本地调试一切正常,到 ...
- RTP/RTCP的时间同步机制
转自:http://blog.csdn.net/leesphone/article/details/5571972 RTP支持传送不同codec的steaming,不同codec的clock rate ...
- Unity3D Log 收集机制
最近做项目的时候发现,需要有一个完整的log机制.这样不仅方便调试而且方便观察. 一.需求 目前我认为一个完善的log机制应该是这样的. 一.双击定位 二.生命周期是全局的 三.输出包括consloe ...
- android log写入机制
这几天和华为的leader面试了下.感觉不错.关键是小女.不容易.是技术面啊.我说的不容易不是面试不容易,是说在华为写代码的小女不容易.哥走南闯北这么多年,女人代码写的好真不多. 其实在任何时候,只要 ...
- Hadoop记录-Federation联邦机制
在Hadoop2.0之前,HDFS的单NameNode设计带来诸多问题: 单点故障.内存受限,制约集群扩展性和缺乏隔离机制(不同业务使用同一个NameNode导致业务相互影响)等 为了解决这些问题, ...
- JAVA记录-redis缓存机制介绍(一)
1.redis介绍 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Re ...
- 在Go语言中记录log:seelog包
前两周调bug调的吐血,虽然解决了但是还是挺浪费时间的.跟同事聊了聊,觉得我们现在项目中的日志记录太少了,导致出了问题不知道怎么下手,还得自己改代码记录日志,然后排查问题.这样如果将来还有bug的话还 ...
随机推荐
- 神马是AB測试?
手机响起了短信提示音,桂芬拿起手机,滑动解锁,看到是来福的短信,心里不禁一阵小鹿乱撞. "喜欢看<冰封重生之门>吗?" 如此充满暗示意味的短信让桂芬激动 ...
- Tuxedo学习门户网站
中间件简介: 介于客户机和server之间的夹层,突破了传统的c/s架构,为构建大规模,高性能.分布式c/s应用程序提供了通信.事物,安全.容错等基础服务,屏蔽了底层应用细节,应用程序不必从底层开发, ...
- Android开发框架SmartAndroid2.0 强劲框架
SmartAndroid 是一个功能强劲的 Android 框架,作为一个简单而"优雅"的工具库包,它能够为 Android 开发人员建立功能完好的Android 应用程序. 经过 ...
- 《炉石传说》建筑设计欣赏(6):卡&在执行数据时,组织能力
上一篇文章我们看到了<炉石传说>核心存储卡的数据,今天,我们不断探索卡&身手. 基本的类 通过之前的分析,卡牌&技能涉及到几个类体系:Entity.Actor.Card.S ...
- redis client protocol 分解
在官方网站http://redis.io/topics/protocol我们必须redis通信协议做说明. 根据以下某些原因.我想解决redis client protocol: 1.足够了解通信协议 ...
- Object-C 新手教程
大纲 開始吧 下载这篇教学 设定环境 前言 编译 hello world 创建 Classes @interface @implementation 把它们凑在一起 具体说明... 多重參数 建构子( ...
- sqlite3触发器的使用
研究了一下osx下dock中应用的存储,位于~/Library/Application Support/Dock/下一个比較名字比較长的db文件里,之前简单的介绍过osx launchpad图标的删除 ...
- Apple Watch 1.0 开发介绍 1.3 简介 WatchKit App 架构
WatchKit app和WatchKit extension一起实现了app的界面.当用户在Apple Watch中操作时,WatchKit app从storyboards中选择合适的场景.比如,如 ...
- poj 2762 Going from u to v or from v to u? (推断它是否是一个薄弱环节图)
意甲冠军:给定一个有向图有m单向边缘.免费推断是否两点起来(a可以b要么b可以a或最多彼此),该请求 弱联通重量. 算法: 缩点求强连通分量.然后又一次建图.推断新图是否是一条单链,即不能分叉,假设分 ...
- poj 3013 Big Christmas Tree (dij+优先级队列优化 求最短)
模板 意甲冠军:给你一个图,1始终根,每一方都有单价值,每个点都有权重新. 每个边缘的价格值 = sum(后继结点重)*单价方值. 最低价格要求树值,它构成了一棵树n-1条边的最小价值. 算法: 1. ...