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管理增量日志并提供查询的更多相关文章

  1. 批量管理增量日志(seek、tell)

    f = open('/usr/home/yongsan/size_text','r+') f.read()

  2. 数据库增量日志监听canal

    概述 canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 起源:早期,阿里巴巴B2B公司 ...

  3. 转 -Filebeat + Redis 管理 LOG日志实践

    Filebeat + Redis 管理 LOG日志实践 小赵营 关注 2019.01.06 17:52* 字数 1648 阅读 24评论 0喜欢 2 引用 转载 请注明出处 某早上,领导怒吼声远远传来 ...

  4. ERP设计之系统基础管理(BS)-日志模块设计(转载)

    原文地址:8.ERP设计之系统基础管理(BS)-日志模块设计作者:ShareERP 日志模块基本要素包括: 用户会话.登录.注销.模块加载/卸载.数据操作(增/删/改/审/弃/关等等).数据恢复.日志 ...

  5. canal 基于Mysql数据库增量日志解析

    canal 基于Mysql数据库增量日志解析  1.前言  最近太多事情 工作的事情,以及终身大事等等 耽误更新,由于最近做项目需要同步监听 未来电视 mysql的变更了解到公司会用canal做增量监 ...

  6. MySQL基础篇(07):用户和权限管理,日志体系简介

    本文源码:GitHub·点这里 || GitEE·点这里 一.MySQL用户 1.基础描述 在数据库的使用过程中,用户作为访问数据库的鉴权因素,起到非常重要的作用,安装MySQL时会自动生成一个roo ...

  7. 使用logrotate管理nginx日志文件

    本文转载自:http://linux008.blog.51cto.com/2837805/555829 描述:linux日志文件如果不定期清理,会填满整个磁盘.这样会很危险,因此日志管理是系统管理员日 ...

  8. logging日志管理-将日志写入文件

    # -*- coding: cp936 -*- # test.py #http://blog.chinaunix.net/uid-27571599-id-3492860.html #logging日志 ...

  9. logging日志管理--将日志打印在屏幕上

    # -*- coding: cp936 -*- # test.py #http://blog.chinaunix.net/uid-27571599-id-3492860.html #logging日志 ...

随机推荐

  1. (新手)使用pandas操作EXCEL

    import pandas as pdimport numpy as npfrom pandas import DataFrame,Series#path = r'C:\Users\tsl\Deskt ...

  2. 动态规划:HDU1160-FatMouse's Speed(记录动态规划状态转移过程)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  3. (洛谷)P1019 单词接龙

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙" ...

  4. 《鸟哥的Linux私房菜》学习笔记(5)——权限管理

    一.权限的基本概念                                                   权限:访问计算机资源或服务的访问能力. Linux中,每一个资源或者服务的权限, ...

  5. VS2010Datatable查看器查看超时(Microsoft.VisualStudio.DebuggerVisualizers)

    这个问题由来已久,却一直没有找到原因.大家都知道,VisualStudio的DebuggerVisualizers是一个非常方便的插件,可以帮助我们调试时查看Datatable视图,前阵子突然发现在查 ...

  6. 6 json和ajax传递api数据

    1 2 3 4 https://swapi.co/ <h1>Hello Reqwest!</h1> <script> var a = {} reqwest({ ur ...

  7. ios开发第一步--虚拟机安装MAC OS X

    暂时还没买Macbook,先用虚拟机练练手. 先说说准备工作,我是在win8下安装的,这个不是关键的,只要Vmware版本和MAC OS X版本确定就行了,win7下同样可以. 1.虚拟机Vmware ...

  8. Python Unicode与中文处理

    转自:http://blog.csdn.net/dao123mao/article/details/5396497 python中的unicode是让人很困惑.比较难以理解的问题,本文力求彻底解决这些 ...

  9. Memcached相关内容总结

    1.Memcached常用命令总结 Memcached命令格式一般为: command 其中描述如下: 参数 描述 command 操作命令,一般为set/add/replace/get/delete ...

  10. Wordpress 文章添加副标题

    后台编辑区添加自定义副标题字段 /** * Add Subtitle in all post */ function article_subtitle( $post ) { if ( ! in_arr ...