跟踪对表的访问

简介: 跟踪对表的访问

加入我们要跟踪对某个表的所有访问。由于 __index__newindex 元方法都是在表中的索引不存在的时候才有用,因此,捕获对一个表所有访问的唯一方式是保持表是空的。如果要监控对一个表的所有访问,那么需要为真正的表创建一个代理proxy )。这个代理是一个空的表,具有用于跟踪所有访问并将访问重定向到原来的表的合理方法。

function track (t)
  local proxy = {}          -- ‘t’的代理表
  -- 为代理创建元表
  local mt = {
    __index = function (_, k)
      print("*access to element " .. tostring(k))
      return t[k]                                           -- 访问原来的表
    end,
    __newindex = function (_, k, v)
      print("*update of element " .. tostring(k) .. " to " .. tostring(v))
      t[k] = v          -- 更新原来的表
    end,
    __pairs = function ()
      return function (_, k)                                    -- 迭代函数
        local nextkey, nextvalue = next(t, k)
        if nextkey ~= nil then                                  -- 避免最后一个值
          print("*traversing element " .. tostring(nextkey))
        end
        return nextkey, nextvalue
      end
    end,
    __len = function () return #t end
  }
  setmetatable(proxy, mt)
  return proxy
end


以下展示了上述代码的用法:

> t = {}
> t = track(t)
> t[2] = "hello"    --> *update of element 2 to hello
> print(t[2])       --> *access to element 2
                    --> hello


元方法 __index__newindex 按照我们设计的规则跟踪每一个访问并将其重定向到原来的表中。元方法 __pairs 使得我们能够像遍历原来的表一样遍历代理,从而跟踪所有的访问。最后,元方法 __len 通过代理实现了长度操作符:

t = track({10, 20})
print(#t)                                     --> 2
for k, v in pairs(t) do print(k, v) end
--> *traversing element 1
--> 1    10
--> *traversing element 2
--> 2    20


如果想要同时监控几个表,并不需要为每个表创建不同的元表。相反,只要以某种形式将每个代理与其原始表映射起来,并且让所有的代理共享一个公共的元表即可。这个问题与把表与其默认值关联起来的问题类似,因此可以采用相同的解决方式。例如,可以把原来的表保存在代理表的一个特殊的字段中,或者使用一个对偶表示建立代理与相应表的映射。

目录
相关文章
|
canal 存储 缓存
如何优雅的记录操作日志
操作日志几乎存在于每个系统中,而这些系统都有记录操作日志的一套 API。操作日志和系统日志不一样,操作日志必须要做到简单易懂。所以如何让操作日志不跟业务逻辑耦合,如何让操作日志的内容易于理解,如何让操作日志的接入更加简单?上面这些都是本文要回答的问题。我们主要围绕着如何“优雅”地记录操作日志展开描述,希望对从事相关工作的同学能够有所帮助或者启发。
643 0
如何优雅的记录操作日志
|
缓存 Java Spring
如何优雅地记录操作日志?(3)
如何优雅地记录操作日志?
423 0
|
Java Spring
如何优雅地记录操作日志?(2)
如何优雅地记录操作日志?
307 0
|
存储 Java 数据库
如何优雅地记录操作日志?(4)
如何优雅地记录操作日志?
381 0
|
canal 存储 Java
如何优雅地记录操作日志?(1)
如何优雅地记录操作日志?
793 0
|
API
日志粒度总结:“应当在哪些地方记录日志,记录时应当记录哪些信息?”
概述 在浏览 v2 社区进行学习交流时,看到了一篇 “日志的粒度请教?” 的帖子,于是仔细思考了此问题,并且将自己在工作过程中总结的经验分享给大家,欢迎大家互相讨论学习。 内容 总结了以下几点: API 的 I/O 日志,也就是请求参数和响应内容记录日志,这相当于整个系统的大门了,访问日志在排错.
3250 0