C#使用SSDB管理增量日志并提供查询
Program.cs
using System;
using System.Text;
using CommonLinkLibrary.Util;
using Newtonsoft.Json; namespace SSDB
{
class Program
{
static void Main(string[] args)
{
InitSsdb(); var channelName = "PersonUpdateLog";
var channelNameKeys = channelName + "_Keys";
var ssdb = ConnectionPool.GetSocket();
ssdb.zclear(channelName);
ssdb.del(channelNameKeys);
Console.WriteLine("清空"+channelName+"成功!"); for (var i = ; i <= ; i++)
{
var pk = GetPrimaryKey(ssdb, channelNameKeys);
var myBean = new PersonInfoLogBean
{
Action = "新增",
NewPersonName = "黄海" + i,
OldPersonName = "黄海" + i,
PersonId = i.ToString(),
OldAge = i.ToString(),
NewAge = i.ToString()
};
var msg = JsonConvert.SerializeObject(myBean);
ssdb.zset(Encoding.UTF8.GetBytes(channelName), Encoding.UTF8.GetBytes(msg), pk);
} for (var i = ; i <= ; i++)
{
var pk = GetPrimaryKey(ssdb, channelNameKeys);
var myBean = new PersonInfoLogBean
{
Action = "修改",
NewPersonName = "(新)黄海" + i,
OldPersonName = "(旧)黄海" + i,
PersonId = i.ToString(),
OldAge = i.ToString(),
NewAge = i.ToString()
};
var msg = JsonConvert.SerializeObject(myBean);
ssdb.zset(Encoding.UTF8.GetBytes(channelName), Encoding.UTF8.GetBytes(msg), pk);
} for (var i = ; i <= ; i++)
{
var pk = GetPrimaryKey(ssdb, channelNameKeys);
var myBean = new PersonInfoLogBean
{
Action = "删除",
NewPersonName = "(新)黄海" + i,
OldPersonName = "(旧)黄海" + i,
PersonId = i.ToString(),
OldAge = i.ToString(),
NewAge = i.ToString()
};
var msg = JsonConvert.SerializeObject(myBean);
ssdb.zset(Encoding.UTF8.GetBytes(channelName), Encoding.UTF8.GetBytes(msg), pk);
}
Console.WriteLine("保存成功!"); const int size = ;
var startId = ;
while (true)
{
var keys = ssdb.zscan(channelName, "", startId, , size);
for (var i = ; i < keys.Length; i++)
{
Console.WriteLine(keys[i].Key + " " + keys[i].Value);
}
if (size != keys.Length)
{
break;
}
else
{
startId = startId + size;
}
}
ConnectionPool.PutSocket(ssdb);
Console.ReadKey();
}
public static void InitSsdb()
{
//连接池的初始化工作
var serverIp = "10.10.6.199";
ConnectionPool.InitializeConnectionPool(serverIp, , , );
} public static long GetPrimaryKey(SsdbClient ssdb, string primaryKeyName)
{
return ssdb.incr(Encoding.UTF8.GetBytes(primaryKeyName), );
}
}
}
ConnectionPool.cs
using System;
using System.Collections.Generic;
using System.Threading; namespace CommonLinkLibrary.Util
{
public static class ConnectionPool
{
/// <summary>
/// Queue of available socket connections.
/// </summary>
private static Queue<SsdbClient> _availableSockets; /// <summary>
/// The maximum size of the connection pool.
/// </summary>
private static int _poolMaxSize = ; private static string _hostIpAddress;
private static int _hostPortNumber; /// <summary>
/// Created host Connection counter
/// </summary>
private static int _socketCounter; public static bool Initialized; /// <summary>
/// Initialize host Connection pool
/// </summary>
/// <param name="hostPortNumber"></param>
/// <param name="minConnections">Initial number of connections</param>
/// <param name="maxConnections">The maximum size of the connection pool</param>
/// <param name="hostIpAddress"></param>
public static void InitializeConnectionPool(string hostIpAddress, int hostPortNumber, int minConnections,
int maxConnections)
{
_socketCounter = ;
_poolMaxSize = maxConnections;
_hostIpAddress = hostIpAddress;
_hostPortNumber = hostPortNumber; _availableSockets = new Queue<SsdbClient>(); for (var i = ; i < minConnections; i++)
{
var cachedSocket = OpenSocket(hostIpAddress, hostPortNumber);
PutSocket(cachedSocket);
} Initialized = true;
} /// <summary>
/// Get an open socket from the connection pool.
/// </summary>
/// <returns>Socket returned from the pool or new socket opened. </returns>
public static SsdbClient GetSocket()
{
//如果连接池中还有可用的连接,那么调用
if (_availableSockets.Count > )
{
lock (_availableSockets)
{
SsdbClient socket = null;
while (_availableSockets.Count > )
{
socket = _availableSockets.Dequeue(); if (socket.Connected)
{
return socket;
}
socket.Close();
Interlocked.Decrement(ref _socketCounter);
}
}
}
//如果没有可用的连接,那么新打开一个连接
return OpenSocket(_hostIpAddress, _hostPortNumber);
} /// <summary>
/// Return the given socket back to the socket pool.
/// </summary>
/// <param name="socket">Socket connection to return.</param>
public static void PutSocket(SsdbClient socket)
{
lock (_availableSockets)
{
if (_availableSockets.Count < _poolMaxSize) // Configuration Value
{
if (socket != null)
{
if (socket.Connected)
{
_availableSockets.Enqueue(socket);
}
else
{
socket.Close();
}
}
}
else
{
socket.Close();
}
}
} /// <summary>
/// Open a new socket connection.
/// </summary>
/// <returns>Newly opened socket connection.</returns>
private static SsdbClient OpenSocket(string hostIpAddress, int hostPortNumber)
{
if (_socketCounter < _poolMaxSize)
{
Interlocked.Increment(ref _socketCounter);
var client = new SsdbClient(hostIpAddress, hostPortNumber);
return client;
}
throw new Exception("Connection Pool reached its limit");
}
}
}
Link.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text; namespace CommonLinkLibrary.Util
{
internal class Link : IDisposable
{
private MemoryStream _recvBuf = new MemoryStream(*);
private TcpClient _sock;
//供程序员显式调用的Dispose方法
public void Dispose()
{
_recvBuf.Dispose();
close();
} //protected的Dispose方法,保证不会被外部调用。
//传入bool值disposing以确定是否释放托管资源 //供GC调用的析构函数
~Link()
{
close();
}
public Link(string host, int port)
{
_sock = new TcpClient(host, port) {NoDelay = true};
_sock.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
} public void close()
{
if (_sock != null)
{
_sock.Close();
}
_sock = null;
} public List<byte[]> request(string cmd, params string[] args)
{
var req = new List<byte[]>( + args.Length) {Encoding.UTF8.GetBytes(cmd)};
foreach (var s in args)
{
req.Add(Encoding.UTF8.GetBytes(s));
}
return request(req);
} public List<byte[]> request(string cmd, params byte[][] args)
{
var req = new List<byte[]>( + args.Length) {Encoding.UTF8.GetBytes(cmd)};
req.AddRange(args);
return request(req);
} public List<byte[]> request(List<byte[]> req)
{
var buf = new MemoryStream();
foreach (var p in req)
{
if(p!=null)
{
var len = Encoding.UTF8.GetBytes(p.Length.ToString());
buf.Write(len, , len.Length);
buf.WriteByte((byte)'\n');
buf.Write(p, , p.Length);
buf.WriteByte((byte)'\n');
}
}
buf.WriteByte((byte) '\n'); var bs = buf.GetBuffer();
_sock.GetStream().Write(bs, , (int) buf.Length);
//Console.Write(Encoding.UTF8.GetString(bs, 0, (int)buf.Length));
return recv();
} private List<byte[]> recv()
{
while (true)
{
var ret = parse();
if (ret != null)
{
return ret;
}
var bs = new byte[];
var len = _sock.GetStream().Read(bs, , bs.Length);
//Console.WriteLine("<< " + Encoding.UTF8.GetString(bs));
_recvBuf.Write(bs, , len);
}
} private static int memchr(byte[] bs, byte b, int offset)
{
for (var i = offset; i < bs.Length; i++)
{
if (bs[i] == b)
{
return i;
}
}
return -;
} private List<byte[]> parse()
{
var list = new List<byte[]>();
var buf = _recvBuf.GetBuffer(); var idx = ;
while (true)
{
var pos = memchr(buf, (byte) '\n', idx);
//System.out.println("pos: " + pos + " idx: " + idx);
if (pos == -)
{
break;
}
if (pos == idx || (pos == idx + && buf[idx] == '\r'))
{
idx += ; // if '\r', next time will skip '\n'
// ignore empty leading lines
if (list.Count == )
{
continue;
}
var left = (int) _recvBuf.Length - idx;
_recvBuf = new MemoryStream();
if (left > )
{
_recvBuf.Write(buf, idx, left);
}
return list;
}
var lens = new byte[pos - idx];
Array.Copy(buf, idx, lens, , lens.Length);
var len = int.Parse(Encoding.UTF8.GetString(lens)); idx = pos + ;
if (idx + len >= _recvBuf.Length)
{
break;
}
var data = new byte[len];
Array.Copy(buf, idx, data, , data.Length); //Console.WriteLine("len: " + len + " data: " + Encoding.UTF8.GetString(data));
idx += len + ; // skip '\n'
list.Add(data);
}
return null;
}
}
}
PersonInfoLogBean.cs
namespace SSDB
{
class PersonInfoLogBean
{
public string Action { get; set; }
public string PersonId { get; set; }
public string OldPersonName { get; set; }
public string NewPersonName { get; set; } public string OldAge { get; set; }
public string NewAge { get; set; } }
}
SsdbClient.cs
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text; namespace CommonLinkLibrary.Util
{
public class SsdbClient : TcpClient
{
private readonly Link _link;
private string _respCode; public SsdbClient(string hostIpAddress, int hostPortNumber) : base(hostIpAddress, hostPortNumber)
{
_link = new Link(hostIpAddress, hostPortNumber);
} public List<byte[]> request(string cmd, params string[] args)
{
return _link.request(cmd, args);
} public List<byte[]> request(string cmd, params byte[][] args)
{
return _link.request(cmd, args);
} public List<byte[]> request(List<byte[]> req)
{
return _link.request(req);
} private byte[] _bytes(string s)
{
if (s == null) return null;
return Encoding.UTF8.GetBytes(s);
} private string _string(byte[] bs)
{
return Encoding.UTF8.GetString(bs);
} private KeyValuePair<string, byte[]>[] parse_scan_resp(List<byte[]> resp)
{
_respCode = _string(resp[]); var size = (resp.Count - )/;
var kvs = new KeyValuePair<string, byte[]>[size];
for (var i = ; i < size; i += )
{
var key = _string(resp[i* + ]);
var val = resp[i* + ];
kvs[i] = new KeyValuePair<string, byte[]>(key, val);
}
return kvs;
} /***** kv *****/ public bool exists(byte[] key)
{
var resp = request("exists", key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return (_string(resp[]) == "" ? true : false);
} public bool exists(string key)
{
return exists(_bytes(key));
} public void set(byte[] key, byte[] val)
{
var resp = request("set", key, val);
_respCode = _string(resp[]);
} public void set(string key, string val)
{
set(_bytes(key), _bytes(val));
} /// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="val"></param>
/// <returns>returns true if name.key is found, otherwise returns false.</returns>
public bool get(byte[] key, out byte[] val)
{
val = null;
var resp = request("get", key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
val = resp[];
return true;
} public bool get(string key, out byte[] val)
{
return get(_bytes(key), out val);
} public bool get(string key, out string val)
{
val = null;
byte[] bs;
if (!get(key, out bs))
{
return false;
}
val = _string(bs);
return true;
} public void del(byte[] key)
{
var resp = request("del", key);
_respCode = _string(resp[]);
} public void del(string key)
{
del(_bytes(key));
} public KeyValuePair<string, byte[]>[] scan(string key_start, string key_end, long limit)
{
var resp = request("scan", key_start, key_end, limit.ToString());
return parse_scan_resp(resp);
} public KeyValuePair<string, byte[]>[] rscan(string key_start, string key_end, long limit)
{
var resp = request("rscan", key_start, key_end, limit.ToString());
return parse_scan_resp(resp);
} /***** hash *****/ public void hset(byte[] name, byte[] key, byte[] val)
{
var resp = request("hset", name, key, val);
_respCode = _string(resp[]);
} public void hset(string name, string key, byte[] val)
{
hset(_bytes(name), _bytes(key), val);
} public void hset(string name, string key, string val)
{
hset(_bytes(name), _bytes(key), _bytes(val));
} /// <summary>
/// </summary>
/// <param name="name"></param>
/// <param name="key"></param>
/// <param name="val"></param>
/// <returns>returns true if name.key is found, otherwise returns false.</returns>
public bool hget(byte[] name, byte[] key, out byte[] val)
{
val = null;
var resp = request("hget", name, key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
val = resp[];
return true;
} public bool hget(string name, string key, out byte[] val)
{
return hget(_bytes(name), _bytes(key), out val);
} public bool hget(string name, string key, out string val)
{
val = null;
byte[] bs;
if (!hget(name, key, out bs))
{
return false;
}
val = _string(bs);
return true;
} public void hdel(byte[] name, byte[] key)
{
var resp = request("hdel", name, key);
_respCode = _string(resp[]);
} public void hdel(string name, string key)
{
hdel(_bytes(name), _bytes(key));
} public bool hexists(byte[] name, byte[] key)
{
var resp = request("hexists", name, key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return (_string(resp[]) == "" ? true : false);
} public bool hexists(string name, string key)
{
return hexists(_bytes(name), _bytes(key));
} public long hsize(byte[] name)
{
var resp = request("hsize", name);
_respCode = _string(resp[]);
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return long.Parse(_string(resp[]));
} public void hclear(string name)
{
request("hclear", _bytes(name));
}
public void zclear(string name)
{
request("zclear", _bytes(name));
}
public long hsize(string name)
{
return hsize(_bytes(name));
} public KeyValuePair<string, byte[]>[] hscan(string name, string key_start, string key_end, long limit)
{
var resp = request("hscan", name, key_start, key_end, limit.ToString());
return parse_scan_resp(resp);
} public KeyValuePair<string, byte[]>[] hrscan(string name, string key_start, string key_end, long limit)
{
var resp = request("hrscan", name, key_start, key_end, limit.ToString());
return parse_scan_resp(resp);
} public void multi_hset(byte[] name, KeyValuePair<byte[], byte[]>[] kvs)
{
var req = new byte[(kvs.Length*) + ][];
req[] = name;
for (var i = ; i < kvs.Length; i++)
{
req[(*i) + ] = kvs[i].Key;
req[(*i) + ] = kvs[i].Value;
}
var resp = request("multi_hset", req);
_respCode = _string(resp[]);
} public void multi_hset(string name, KeyValuePair<string, string>[] kvs)
{
var req = new KeyValuePair<byte[], byte[]>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
req[i] = new KeyValuePair<byte[], byte[]>(_bytes(kvs[i].Key), _bytes(kvs[i].Value));
}
multi_hset(_bytes(name), req);
} public void multi_hdel(byte[] name, byte[][] keys)
{
var req = new byte[keys.Length + ][];
req[] = name;
for (var i = ; i < keys.Length; i++)
{
req[i + ] = keys[i];
}
var resp = request("multi_hdel", req);
_respCode = _string(resp[]);
} public void multi_hdel(string name, string[] keys)
{
var req = new byte[keys.Length][];
for (var i = ; i < keys.Length; i++)
{
req[i] = _bytes(keys[i]);
}
multi_hdel(_bytes(name), req);
} public KeyValuePair<string, byte[]>[] multi_hget(byte[] name, byte[][] keys)
{
var req = new byte[keys.Length + ][];
req[] = name;
for (var i = ; i < keys.Length; i++)
{
req[i + ] = keys[i];
}
var resp = request("multi_hget", req);
var ret = parse_scan_resp(resp); return ret;
} public KeyValuePair<string, byte[]>[] multi_hget(string name, string[] keys)
{
var req = new byte[keys.Length][];
for (var i = ; i < keys.Length; i++)
{
req[i] = _bytes(keys[i]);
}
return multi_hget(_bytes(name), req);
} /***** zset *****/ public void zset(byte[] name, byte[] key, long score)
{
var resp = request("zset", name, key, _bytes(score.ToString()));
_respCode = _string(resp[]);
} public void zset(string name, string key, long score)
{
zset(_bytes(name), _bytes(key), score);
}
public long incr(byte[] name, long increment)
{
var resp = request("incr", name, _bytes(increment.ToString()));
_respCode = _string(resp[]);
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return long.Parse(_string(resp[]));
} public long zincr(byte[] name, byte[] key, long increment)
{
var resp = request("zincr", name, key, _bytes(increment.ToString()));
_respCode = _string(resp[]);
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return long.Parse(_string(resp[]));
} public long zincr(string name, string key, long increment)
{
return zincr(_bytes(name), _bytes(key), increment);
} /// <summary>
/// </summary>
/// <param name="name"></param>
/// <param name="key"></param>
/// <param name="score"></param>
/// <returns>returns true if name.key is found, otherwise returns false.</returns>
public bool zget(byte[] name, byte[] key, out long score)
{
score = -;
var resp = request("zget", name, key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
score = long.Parse(_string(resp[]));
return true;
} public bool zget(string name, string key, out long score)
{
return zget(_bytes(name), _bytes(key), out score);
} public void zdel(byte[] name, byte[] key)
{
var resp = request("zdel", name, key);
_respCode = _string(resp[]);
} public void zdel(string name, string key)
{
zdel(_bytes(name), _bytes(key));
} public long zsize(byte[] name)
{
var resp = request("zsize", name);
_respCode = _string(resp[]);
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return long.Parse(_string(resp[]));
} public long zsize(string name)
{
return zsize(_bytes(name));
} public bool zexists(byte[] name, byte[] key)
{
var resp = request("zexists", name, key);
_respCode = _string(resp[]);
if (_respCode == "not_found")
{
return false;
}
if (resp.Count != )
{
throw new Exception("Bad response!");
}
return (_string(resp[]) == "" ? true : false);
} public bool zexists(string name, string key)
{
return zexists(_bytes(name), _bytes(key));
} public KeyValuePair<string, long>[] zrange(string name, int offset, int limit)
{
var resp = request("zrange", name, offset.ToString(), limit.ToString());
var kvs = parse_scan_resp(resp);
var ret = new KeyValuePair<string, long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
var key = kvs[i].Key;
var score = long.Parse(_string(kvs[i].Value));
ret[i] = new KeyValuePair<string, long>(key, score);
}
return ret;
} public KeyValuePair<string, long>[] zrrange(string name, int offset, int limit)
{
var resp = request("zrrange", name, offset.ToString(), limit.ToString());
var kvs = parse_scan_resp(resp);
var ret = new KeyValuePair<string, long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
var key = kvs[i].Key;
var score = long.Parse(_string(kvs[i].Value));
ret[i] = new KeyValuePair<string, long>(key, score);
}
return ret;
} public KeyValuePair<string, long>[] zscan(string name, string key_start, long score_start, long score_end,
long limit)
{
var scoreS = "";
var scoreE = "";
if (score_start != long.MinValue)
{
scoreS = score_start.ToString();
}
if (score_end != long.MaxValue)
{
scoreE = score_end.ToString();
}
var resp = request("zscan", name, key_start, scoreS, scoreE, limit.ToString());
var kvs = parse_scan_resp(resp);
var ret = new KeyValuePair<string, long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
var key = kvs[i].Key;
var score = long.Parse(_string(kvs[i].Value));
ret[i] = new KeyValuePair<string, long>(key, score);
}
return ret;
} public KeyValuePair<string, long>[] zrscan(string name, string key_start, long score_start, long score_end,
long limit)
{
var scoreS = "";
var scoreE = "";
if (score_start != long.MaxValue)
{
scoreS = score_start.ToString();
}
if (score_end != long.MinValue)
{
scoreE = score_end.ToString();
}
var resp = request("zrscan", name, key_start, scoreS, scoreE, limit.ToString());
var kvs = parse_scan_resp(resp);
var ret = new KeyValuePair<string, long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
var key = kvs[i].Key;
var score = long.Parse(_string(kvs[i].Value));
ret[i] = new KeyValuePair<string, long>(key, score);
}
return ret;
} public void multi_zset(byte[] name, KeyValuePair<byte[], long>[] kvs)
{
var req = new byte[(kvs.Length*) + ][];
req[] = name;
for (var i = ; i < kvs.Length; i++)
{
req[(*i) + ] = kvs[i].Key;
req[(*i) + ] = _bytes(kvs[i].Value.ToString());
}
var resp = request("multi_zset", req);
_respCode = _string(resp[]);
} public void multi_zset(string name, KeyValuePair<string, long>[] kvs)
{
var req = new KeyValuePair<byte[], long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
req[i] = new KeyValuePair<byte[], long>(_bytes(kvs[i].Key), kvs[i].Value);
}
multi_zset(_bytes(name), req);
} public void multi_zdel(byte[] name, byte[][] keys)
{
var req = new byte[keys.Length + ][];
req[] = name;
for (var i = ; i < keys.Length; i++)
{
req[i + ] = keys[i];
}
var resp = request("multi_zdel", req);
_respCode = _string(resp[]);
} public void multi_zdel(string name, string[] keys)
{
var req = new byte[keys.Length][];
for (var i = ; i < keys.Length; i++)
{
req[i] = _bytes(keys[i]);
}
multi_zdel(_bytes(name), req);
} public KeyValuePair<string, long>[] multi_zget(byte[] name, byte[][] keys)
{
var req = new byte[keys.Length + ][];
req[] = name;
for (var i = ; i < keys.Length; i++)
{
req[i + ] = keys[i];
}
var resp = request("multi_zget", req);
var kvs = parse_scan_resp(resp);
var ret = new KeyValuePair<string, long>[kvs.Length];
for (var i = ; i < kvs.Length; i++)
{
var key = kvs[i].Key;
var score = long.Parse(_string(kvs[i].Value));
ret[i] = new KeyValuePair<string, long>(key, score);
}
return ret;
} public KeyValuePair<string, long>[] multi_zget(string name, string[] keys)
{
var req = new byte[keys.Length][];
for (var i = ; i < keys.Length; i++)
{
req[i] = _bytes(keys[i]);
}
return multi_zget(_bytes(name), req);
}
}
}
C#使用SSDB管理增量日志并提供查询的更多相关文章
- 批量管理增量日志(seek、tell)
f = open('/usr/home/yongsan/size_text','r+') f.read()
- 数据库增量日志监听canal
概述 canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 起源:早期,阿里巴巴B2B公司 ...
- 转 -Filebeat + Redis 管理 LOG日志实践
Filebeat + Redis 管理 LOG日志实践 小赵营 关注 2019.01.06 17:52* 字数 1648 阅读 24评论 0喜欢 2 引用 转载 请注明出处 某早上,领导怒吼声远远传来 ...
- ERP设计之系统基础管理(BS)-日志模块设计(转载)
原文地址:8.ERP设计之系统基础管理(BS)-日志模块设计作者:ShareERP 日志模块基本要素包括: 用户会话.登录.注销.模块加载/卸载.数据操作(增/删/改/审/弃/关等等).数据恢复.日志 ...
- canal 基于Mysql数据库增量日志解析
canal 基于Mysql数据库增量日志解析 1.前言 最近太多事情 工作的事情,以及终身大事等等 耽误更新,由于最近做项目需要同步监听 未来电视 mysql的变更了解到公司会用canal做增量监 ...
- MySQL基础篇(07):用户和权限管理,日志体系简介
本文源码:GitHub·点这里 || GitEE·点这里 一.MySQL用户 1.基础描述 在数据库的使用过程中,用户作为访问数据库的鉴权因素,起到非常重要的作用,安装MySQL时会自动生成一个roo ...
- 使用logrotate管理nginx日志文件
本文转载自:http://linux008.blog.51cto.com/2837805/555829 描述:linux日志文件如果不定期清理,会填满整个磁盘.这样会很危险,因此日志管理是系统管理员日 ...
- logging日志管理-将日志写入文件
# -*- coding: cp936 -*- # test.py #http://blog.chinaunix.net/uid-27571599-id-3492860.html #logging日志 ...
- logging日志管理--将日志打印在屏幕上
# -*- coding: cp936 -*- # test.py #http://blog.chinaunix.net/uid-27571599-id-3492860.html #logging日志 ...
随机推荐
- vue之神奇的动态按钮
今天我们将利用vue的条件指令来完成一个简易的动态变色功能按钮 首先我们还是要对vue进行配置,在上篇随笔中有相关下载教学. 然后我们要在html页面上搭建三个简易的按钮,颜色分别为紫,绿和蓝(颜色随 ...
- stark组件前戏(2)之单例模式
单,一个. 例,实例.对象. 通过利用Python模块导入的特性:在Python中,如果已经导入过的文件再被重新导入时候,python不会重新解释一遍,而是选择从内容中直接将原来导入的值拿来用. ...
- Redis实现之对象(四)
类型检查与命令多态 Redis中用于操作键的命令基本上可以分为两种类型:其中一种命令可以对任何类型的键执行,比如DEL命令.EXPIRE命令.RENAME命令.TYPE命令.OBJECT命令等.举个栗 ...
- html调用commonjs规范的js
a.js define(function(require, exports, module) { var test = function(){ console.log("hello worl ...
- TopK-微博今日热门话题
大纲 TopK on single node TopK on multiple nodes Realtime topK with low QPS Realtime topK with high QPS ...
- 与Python的初次见面
一.Python的介绍 python的创始人为吉多.范罗苏姆.1989年的圣诞期间,吉多.范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承. 二.Python是 ...
- 【转】超简单利用UGUI制作圆形小地图
http://sanwen.net/a/ithhtbo.html 由于UI都是Achor自己用PS做的,比较粗糙,大家见谅,不过丝毫不影响功能的实现,下面我们看看今天的笔记: 首先我们看看需要哪些组件 ...
- python发送给邮件 转
这里用到了Python的两个包来发送邮件: smtplib 和 email . Python 的 email 模块里包含了许多实用的邮件格式设置函数,可以用来创建邮件“包裹”.使用的 MIMEText ...
- MySql 存储过程实例(附完整注释)(转)
MySql 存储过程实例(附完整注释) 将下面的语句复制粘贴可以一次性执行完,我已经测试过,没有问题! MySql存储过程简单实例: ...
- Struts2,get/set 自动获取/设置数据ActionSupport 类
主页:http://struts.apache.org/在用户请求和模块化处理方面以及页面的展现这块,Struts2 发挥了强大的作用:相对于传统的Jsp+Servlet 模式,Struts2 更适合 ...