听云 Server for Python 探针公测开启,现在加入,机械键盘抱回家!

2015-08-19 18:14:34 +08:00
 TINGYUN

24h 紧盯显示器的运维为何忽然神秘地有了空余时间?
数年如一日做好救险准备的他们为何突然能正常下班吃上生蚝撸大腰?
改变运维的命运,究竟是何人所为?运维工作变得轻松的背后又隐藏着什么?
这一切的一切,
是工作倦怠开始偷懒?还是准备跳槽另有隐情?
是捡到秘籍修得神功?还是打通二脉融会贯通?
尽请关注《走进科学》暑期特别节目《当运维偶遇听云》,让我们跟随着镜头走进这不为人知的秘密...

听云 Server


领奖姿势


听云身为 SaaS 领域唯一上市新三板的公司, 对加入公测的同学的奖励,也大方的不要不要的:

成功部署听云 Server for Python 探针,发送截图及账户名至 hashuang@tingyun.com , 前 50 名部署成功同学(以收到邮件时间为准), 雷蛇游戏键鼠套装为您双手奉上!

那么问题来了,如何加入公测呢


  1. 来,少年,请先申请一个听云账号 注册来戳我呀 , 并开通听云 Server
  2. 下载并安装 Python 探针
  3. 重启或重新启动应用服务器
  4. 成功部署 Python 探针,监控服务端应用性能,从此老板再也不用担心我因问题发现太晚而造成用户流失,开启人生 easy 模式!

活动细则


每款应用都需要听云

5802 次点击
所在节点    推广
23 条回复
TINGYUN
2015-08-21 19:37:44 +08:00
@glasslion
tingyun-memcache_trace.py

import logging

from tingyun.api.tracert.memcache_node import MemcacheNode
from tingyun.api.objects.object_wrapper import wrap_object, FunctionWrapper
from tingyun.api.tracert.time_trace import TimeTrace
from tingyun.api.transaction.base import current_transaction

_logger = logging.getLogger (__name__)


class MemcacheTrace (TimeTrace ):
def __init__(self, transaction, command ):
super (MemcacheTrace, self ).__init__(transaction )
self.command = command

def create_node (self ):
return MemcacheNode (command=self.command, children=self.children, start_time=self.start_time,
end_time=self.end_time, duration=self.duration, exclusive=self.exclusive )

def terminal_node (self ):
return True


def memcached_trace_wrapper (wrapped, command ):
"""
:return:
"""
def dynamic_wrapper (wrapped, instance, args, kwargs ):
transaction = current_transaction ()
if transaction is None:
return wrapped (*args, **kwargs )

if instance is not None:
_command = command (instance, *args, **kwargs )
else:
_command = command (*args, **kwargs )

with MemcacheTrace (transaction, _command ):
return wrapped (*args, **kwargs )

def literal_wrapper (wrapped, instance, args, kwargs ):
transaction = current_transaction ()
if transaction is None:
return wrapped (*args, **kwargs )

with MemcacheTrace (transaction, command ):
return wrapped (*args, **kwargs )

if callable (command ):
return FunctionWrapper (wrapped, dynamic_wrapper )

return FunctionWrapper (wrapped, literal_wrapper )


# egg: (memcached, Client.append, get )
def wrap_memcache_trace (module, object_path, command ):
wrap_object (module, object_path, memcached_trace_wrapper, (command,))

newrelic-memcache_trace.py

import sys
import types
import time
import logging

import newrelic.core.memcache_node

import newrelic.api.transaction
import newrelic.api.time_trace
import newrelic.api.object_wrapper


_logger = logging.getLogger (__name__)


class MemcacheTrace (newrelic.api.time_trace.TimeTrace ):

node = newrelic.core.memcache_node.MemcacheNode

def __init__(self, transaction, command ):
super (MemcacheTrace, self ).__init__(transaction )

self.command = command

def dump (self, file ):
print >> file, self.__class__.__name__, dict (command=self.command )

def create_node (self ):
return self.node (command=self.command, children=self.children,
start_time=self.start_time, end_time=self.end_time,
duration=self.duration, exclusive=self.exclusive )

def terminal_node (self ):
return True

class MemcacheTraceWrapper (object ):

def __init__(self, wrapped, command ):
if isinstance (wrapped, tuple ):
(instance, wrapped ) = wrapped
else:
instance = None

newrelic.api.object_wrapper.update_wrapper (self, wrapped )

self._nr_instance = instance
self._nr_next_object = wrapped

if not hasattr (self, '_nr_last_object'):
self._nr_last_object = wrapped

self._nr_command = command

def __get__(self, instance, klass ):
if instance is None:
return self
descriptor = self._nr_next_object.__get__(instance, klass )
return self.__class__((instance, descriptor ), self._nr_command )

def __call__(self, *args, **kwargs ):
transaction = newrelic.api.transaction.current_transaction ()

if not transaction:
return self._nr_next_object (*args, **kwargs )

if callable (self._nr_command ):
if self._nr_instance is not None:
command = self._nr_command (self._nr_instance, *args,
**kwargs )
else:
command = self._nr_command (*args, **kwargs )
else:
command = self._nr_command

with MemcacheTrace (transaction, command ):
return self._nr_next_object (*args, **kwargs )

def memcache_trace (command ):
def decorator (wrapped ):
return MemcacheTraceWrapper (wrapped, command )
return decorator

def wrap_memcache_trace (module, object_path, command ):
newrelic.api.object_wrapper.wrap_object (module, object_path,
MemcacheTraceWrapper, (command,))
TINGYUN
2015-08-21 19:39:39 +08:00
@glasslion
tingyun-database.redis.py
from tingyun.api.tracert.redis_trace import wrap_redis_trace
from tingyun.api.tracert.function_trace import wrap_function_trace

rewrite_command = ['setex', 'lrem', 'zadd']
basic_command = [
'append', 'bgrewriteaof', 'bgsave', 'bitcount', 'bitop', 'bitpos', 'blpop', 'brpop', 'brpoplpush', 'client_getname',
'client_kill', 'client_list', 'client_setname', 'config_get', 'config_resetstat', 'config_rewrite', 'config_set',
'connection_pool', 'dbsize', 'debug_object', 'decr', 'delete', 'dump', 'echo', 'eval', 'evalsha', 'execute_command',
'exists', 'expire', 'expireat', 'flushall', 'flushdb', 'from_url', 'get', 'getbit', 'getrange', 'getset', 'hdel',
'hexists', 'hget', 'hgetall', 'hincrby', 'hincrbyfloat', 'hkeys', 'hlen', 'hmget', 'hmset', 'hscan', 'hscan_iter',
'hset', 'hsetnx', 'hvals', 'incr', 'incrby', 'incrbyfloat', 'info', 'keys', 'lastsave', 'lindex', 'linsert', 'llen',
'lock', 'lpop', 'lpush', 'lpushx', 'lrange', 'lrem', 'lset', 'ltrim', 'mget', 'move', 'mset', 'msetnx',
'object', 'parse_response', 'persist', 'pexpire', 'pexpireat', 'pfadd', 'pfcount', 'pfmerge', 'ping',
'pipeline', 'psetex', 'pttl', 'publish', 'pubsub', 'randomkey', 'register_script', 'rename',
'renamenx', 'response_callbacks', 'restore', 'rpop', 'rpoplpush', 'rpush', 'rpushx', 'sadd', 'save',
'scan', 'scan_iter', 'scard', 'script_exists', 'script_flush', 'script_kill', 'script_load', 'sdiff',
'sdiffstore', 'set', 'set_response_callback', 'setbit', 'setex', 'setnx', 'setrange', 'shutdown',
'sinter', 'sinterstore', 'sismember', 'slaveof', 'slowlog_get', 'slowlog_len', 'slowlog_reset',
'smembers', 'smove', 'sort', 'spop', 'srandmember', 'srem', 'sscan', 'sscan_iter', 'strlen', 'substr',
'sunion', 'sunionstore', 'time', 'transaction', 'ttl', 'type', 'unwatch', 'watch', 'zadd', 'zcard',
'zcount', 'zincrby', 'zinterstore', 'zlexcount', 'zrange', 'zrangebylex', 'zrangebyscore', 'zrank',
'zrem', 'zremrangebylex', 'zremrangebyrank', 'zremrangebyscore', 'zrevrange', 'zrevrangebyscore',
'zrevrank', 'zscan', 'zscan_iter', 'zscore', 'zunionstore']


def detect_connection (module ):
"""
:param module:
:return:
"""
if hasattr (module, 'Connection') and hasattr (module.Connection, 'connect'):
wrap_function_trace (module, "Connection.connect", name="connect")


def detect_client_operation (module ):
"""
:param module:
:return:
"""
if hasattr (module, 'StrictRedis'):
for command in basic_command:
if hasattr (module.StrictRedis, command ):
wrap_redis_trace (module, "StrictRedis.%s" % command, command )

if hasattr (module, 'Redis'):
for command in rewrite_command:
if hasattr (module.Redis, command ):
wrap_redis_trace (module, "Redis.%s" % command, command )
elif hasattr (module, 'Redis'):
for command in basic_command:
if hasattr (module.Redis, command ):
wrap_redis_trace (module, "Redis.%s" % command, command )

newrelic_database.nosql_redis.py
import newrelic.api.function_trace

_methods_1 = ['bgrewriteaof', 'bgsave', 'config_get', 'config_set',
'dbsize', 'debug_object', 'delete', 'echo', 'flushall',
'flushdb', 'info', 'lastsave', 'object', 'ping', 'save',
'shutdown', 'slaveof', 'append', 'decr', 'exists',
'expire', 'expireat', 'get', 'getbit', 'getset', 'incr',
'keys', 'mget', 'mset', 'msetnx', 'move', 'persist',
'randomkey', 'rename', 'renamenx', 'set', 'setbit',
'setex', 'setnx', 'setrange', 'strlen', 'substr', 'ttl',
'type', 'blpop', 'brpop', 'brpoplpush', 'lindex',
'linsert', 'llen', 'lpop', 'lpush', 'lpushx', 'lrange',
'lrem', 'lset', 'ltrim', 'rpop', 'rpoplpush', 'rpush',
'rpushx', 'sort', 'sadd', 'scard', 'sdiff', 'sdiffstore',
'sinter', 'sinterstore', 'sismember', 'smembers',
'smove', 'spop', 'srandmember', 'srem', 'sunion',
'sunionstore', 'zadd', 'zcard', 'zcount', 'zincrby',
'zinterstore', 'zrange', 'zrangebyscore', 'zrank', 'zrem',
'zremrangebyrank', 'zremrangebyscore', 'zrevrange',
'zrevrangebyscore', 'zrevrank', 'zscore', 'zunionstore',
'hdel', 'hexists', 'hget', 'hgetall', 'hincrby', 'hkeys',
'hlen', 'hset', 'hsetnx', 'hmset', 'hmget', 'hvals',
'publish']

_methods_2 = ['setex', 'lrem', 'zadd']

def instrument_redis_connection (module ):

newrelic.api.function_trace.wrap_function_trace (
module, 'Connection.connect')

def instrument_redis_client (module ):

if hasattr (module, 'StrictRedis'):
for method in _methods_1:
if hasattr (module.StrictRedis, method ):
newrelic.api.function_trace.wrap_function_trace (
module, 'StrictRedis.%s' % method )
else:
for method in _methods_1:
if hasattr (module.Redis, method ):
newrelic.api.function_trace.wrap_function_trace (
module, 'Redis.%s' % method )

for method in _methods_2:
if hasattr (module.Redis, method ):
newrelic.api.function_trace.wrap_function_trace (module, 'Redis.%s' % method )
alsotang
2015-08-25 15:00:37 +08:00
在这里贴代码也是醉了。。。。。我最近发现个网站挺好用的,在此推荐一下: https://gist.github.com/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/214359

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX