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日志 ...
随机推荐
- python3:判断手机的亮屏状态
在用python对手机做一些自动化操作时,常常会判断手机的亮屏状态,知晓手机的亮屏状态后才好做进一步的动作,如给屏幕解锁等. 用于了解手机的亮屏情况,有一个adb命令可用: adb shell du ...
- iOS SDK中使用NSXMLParser解析XML(iphone网络篇三)
iOS SDK的NSXMLParser解析XML文档是事件驱动模式的,即采用SAX方式来解析XML格式文档.NSXMLParser在处理XML文档的过程中当遇到一些要素(元素.属性.CDATA块.评论 ...
- 【Isamaru, Hound of Honda】SVN常用命令补遗
一些常用的 就是svn commit的时候 都必须是最新版本的东西 不能不是,但是其实只是.svn在控制,所以可以update到最新版本再svn merge -r 20:10 将版本10和20的融合, ...
- 笔记-网络-抓包-wireshark
笔记-网络-抓包-wireshark 1. 开始 环境:win8笔记本,无线网 1.1. 无线网卡设置 因为需抓捕无线网卡上的数据包,需要进行一项设置,如捕获有线网卡,无需设置. 打开 ...
- Maya
建立酒杯的方法(CV曲线) surface(曲面)-- creat cv curve tool-- control vertex(调整图形)[再次creat cv建立厚度,只需要建立酒杯的上口]--- ...
- vijos1083:小白逛公园
小白逛公园 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. 一开始,小白就根据公园的 ...
- MySQL之索引(二)
高性能的索引策略 正确地创建和使用索引是实现高性能查询的基础.在MySQL之索引(一)这一章中我们介绍了各种类型的索引及其对应的优缺点.现在我们一起来看看如何真正地发挥这些索引的优势. 独立的列 我们 ...
- HighCharts实现双Y轴
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.c ...
- 如何选择Android自动化框架的几点拙见
首先由于我自己也是个新手,也是在学习各种框架然后给公司项目选定相应自动化框架,研究移动自动化测试框架也就近段时间而已,所以我只能从我自己今天为止的认知角度给各个框架抒发我自己的拙见,你看是否能从中接纳 ...
- java线程安全问题原因及解决办法
1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...