今天我来分享一个关于日志的问题和解法。
问题
没有界面的后端程序在实际运行中发生了什么事,通常是通过日志来探查。所以日志非常重要。数据库记录了程序运行的结果,日志记录了程序运行的过程。但是日志经常出现一个问题,日志量太多,以至于把重要的日志淹没在里面。未能及时地发现问题,或者当有问题出现的时候,在日志中找原因真的是很痛苦。
对于这个问题,第1招就是把日志进行分级,差不多是每一种日志工具都提供了这个功能。常见的有info、warn、error这些级别。当使用级别进行过滤之后,往往发现日志还是太多。就需要进一步分析原因了。
在实际项目中发现有这么几种情况:
1. 有大量的日志,内容基本相同,只是有一两个值不同。如“发现无法转成long类型的字符串:xxx”
2. 还有一类日志是内容完全相同,如“意外发现xxx属性的值是null”
至于为什么会有大量的这种日志,大概率是它在循环内部,甚至是多重循环的内部。
怕日志多而在写日志代码时犹豫,甚至就不写了。当出问题后找不到日志,无法为定位问题提供帮助。此法不可取。
设置一些标志或计数器来使循环内的同一类日志只打印一条或少数几条,那么日志的逻辑跟业务的逻辑会混在一起,程序的整体逻辑变得复杂。此法是下策。
如何让程序员大胆写日志,而又不会出现日志太多,同时日志的逻辑也很少掺杂到业务逻辑中呢?
我写了一个日志的实用类来解决这个问题。
它是将多条日志拼接为一条来输出。采用“前缀+主体+后缀”的形式,在初始化时设置好前缀和后缀,在接收日志条目时拼接条目,最后的输出形式是“前缀+条目1, 条目2, …+后缀”。如果条目数为0,则前后缀都不会输出。所以,“发现无法转成long类型的字符串:aaa”,“发现无法转成long类型的字符串:bbb”“发现无法转成long类型的字符串:ccc”,会拼接这样一条:“发现无法转成long类型的字符串:aaa,bbb,ccc”。合成后的内容长度就大大减少。
假如类似的情况发生1000次,拼接后的日志还是很长。作为人来讲,只需要看到前面的若干条目,就了解了这个问题,通常是没必要看到全部的值。所以这个日志工具提供了条目数的限制,对于超过限制的条目,则不会输出。比如条目数的限制是2,那输出的结果就是“发现无法转成long类型的字符串:aaa,bbb”
对于内容完全相同的日志,就会直接进行合并,并记录一个次数,不相邻的除外。原本是好几屏幕的“意外发现xxx的值是null”。合并成一条:“[1000*]意外发现xxx的值是null”。(此法是向浏览器的控制台学习)
除此之外,还提供了总长度的限制,即是对“前缀+条目1, 条目2, …+后缀”的总长度的限制。如果某个条目加进去之后整体长度超过这个限制了,那么这个条目就会被丢弃。前缀后缀是不会被丢弃的,但如果“前缀+后缀”已经超出限制了,根据“如果条目数为0,则前后缀都不会输出”最终没有输出。
此日志类实现特定的接口(Closable),做到了即使在业务代码发生异常的情况下,也不会漏了输出优化后日志。用法:
try (LogUtil log = LogUtil.builder().logger(LOGGER).build()) {
// ...A
log.write(“any message”);
// ...B
}
如果A处发生异常,自然没有任何输出。如果B处发生异常,则不影响前面的“any message”的输出。
以上的条目数限制、同值合并、总长度限制等功能可单独使用,也可组合使用。所以可能会看到这样的结果:
“发现无法转成long类型的字符串:aaa,bbb,[99*]aaa,[56*]ccc”
这个日志实用工具是对现有日志组件的封装,而现有的日志组件是log4j。不管使用哪个日志组件,都可以加上这种封装。我并没有修改日志组件,只是给他套了一层“壳”。
实际投入使用后,在我们的项目中发现,有一种相同的日志产生了947条,在过去是刷了好多屏,而且还不知道他多少条,现在合成之后就是一条,并且打上了“[947*]”,不仅没有刷屏,还很清晰的看到了条数。
干净,舒服。
大家好,又见面了,我是你们的朋友全栈君。没想到被Android里的RSA加密折腾了几个小时,主要还是自己对RSA加密的原理不了解,然后网上相关的资料也少。 使用AndroidUtilCode工具类中的EncryptUtils.encryptRSA()加密后的数据怎么也不对,后来自己找了段加密代码,才总算是可以了,这里记录一下。首先我们需要先生成一个RSA的公钥和私钥。RSA加密公钥-----BEGINPUBLICKEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOCSZxJyD9BCPF+E0AwT1v/qdv lMhLKkNbnp1BIrh9bnfuv15mULugWq7ARtWtppZVLHu7H0No6vZQRN66BY3wWbll NPZP2Qg2xV3ubXcDa5CtfdmDbPeN+Ol4s97Gzcn7VL1+3NXzMRLAm1E64hqkrMfE xpr5Okdai0szIb/EvwIDAQAB -----ENDPUBLICKEY-----复制RSA加密私钥-----BEGINPRIVATEKEY----- MIICdw
场景: 需要提交数据,且数据处理后,会跳转页面。(注:数据提交需要post) 思路1: 1.参考ajax提交数据,进行处理,处理成功后返回到客户端 2.在客户端跳转页面 思路2: 使用form表格进行post提交 实现方法:需要创建一个form表格,且数据必须在form表格中,用Input表格元素存起来,效果如下: ///form表单提交 varform2=document.createElement("form"); form2.id="form2"; form2.method="post"; form2.action="buildOrder.do"; //地址id varaddress=document.createElement("input"); address.name="addressId"; address.type="hidden"; address.value=orderAddressId; form2.appendChild
今天看到一份其他公司的晶圆芯片的制作工艺流程,其中有一道工艺是采用亚硫酸金钠溶液经过低温成膜形成黄金层。 我们都知道晶圆在进行金属层沉积的时候,常用溅射或者蒸发的工艺,因此镀膜层厚度一般都不高,特别是镀金子的时候,100g金真的到晶圆上的不会超过20g,浪费啊。流程原文对这两步工序的介绍如下: “金属膜沉积:金属蒸镀是在真空环境下,在光刻后的晶圆表面上蒸镀金属层。本项目采用真空蒸发法,是采用电子束加热将金属原料蒸发沉积到外延片上的一种成膜方法。蒸发原料的分子或原子平均自由程较高,在真空中几乎不予其他分子碰撞和直接到达外延片。到达外延片的原料分子不具有表面移动的能量,立即凝结在晶圆片表面。金属蒸镀使用的主要材料为钛、铂、金、锗、镍。低温成膜:低温成膜工艺是在表面沉积一层金属膜,其中,原料金、硫代硫酸钠盐、氢氧化铵,该工艺工程会产生成膜废液,委外处理。”用电镀镀金确实是个镀厚膜的好方法,镀它100个um,芯片打线效果相当好的。但是电镀前必须有一层导电层。今天详细了解一下晶圆电镀金的原理和工艺。 1、电镀到底是如何玩的呢? 电镀是一种电化学过程,也是一种氧化还原过程.电镀的基本过程是将零件浸
AndroidUI线程是不安全的,子线程中进行UI操作,可能会导致程序的崩溃,解决办法:创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了定义类继承HandlerpublicclassBallHandlerextendsHandler{ ImageViewimageview; Bitmapbitmap; publicBallHandler(ImageViewimageview,Bitmapbitmap){ super(); this.imageview=imageview; this.bitmap=bitmap; } publicvoidhandleMessage(Messagemsg){ bitmap=(Bitmap)msg.obj; imageview.setImageBitmap(bitmap); }复制在线程中,创建Message对象,向Handle发送消息Messagemsg=newMessage(); msg.obj=bitmap;
1、前言 通常而言,系统审计是指记录谁,什么时间,干了什么事儿,具体到本项目中,着重两个方面:一是记录重点业务记录的创建人、创建时间、修改人、修改时间;二是记录重点操作的流水记录,如谁什么时间新增了个什么订单。本篇讲上半部分,既重点业务对象记录的创建人、创建时间,修改人、修改时间,或者准确讲是最后修改人、最后修改时间。 见过也维护过不少系统,这类审计字段,直接跟业务字段赋值或业务逻辑融合在一起,遍布系统各个角落,繁琐是其一,更严重的是如果哪个地方忘记了,那才是大事儿。总之就是,很没技术含量,或者不“政治正确”。那接下来我们就看看怎么样“政治正确”的去实现审计。2、实现 首先,调整DBContext,让审计字段的赋值去横切的处理:publicclassSystemManageDbContext:DbContext { privatereadonlyCurrentUser_currentUser; publicSystemManageDbContext([NotNullAttribute]DbContextOptionsoptions,CurrentUsercurrentUser)
当你遇到单点单应用支撑不住使用的时候,Z哥给你的普适性建议是:先考虑“扩”,再考虑“切”。这个和写代码一样,“增加”新功能往往比在老功能上改容易。“扩”的话先考虑「垂直扩」(加硬件,钱能解决的都不是问题),再考虑「水平扩」(无状态改造+多节点部署,这是小手术)。“切”的话一般就是「垂直切」(根据业务切分,这是大手术),偶尔会用到「水平切」(其实就是单个应用里的分层,比如前后端分离)。第三篇《分布式系统关注点——弹性架构》我们聊了常见的两种「松耦合」架构模式,为的是让应用程序的「伸缩性」更上一层楼。以上这些呢都是应用程序层面的工作。一般情况下,在应用程序层面做做手术,再配合以缓存的充分运用,就可以支撑系统发展很长时间了。特别是数据量不大,只是请求量大的「CPU密集型」场景。但是,如果所处的工作场景是一个非常成熟且具有一定规模的项目,越发展到后面瓶颈总是出现在数据库这里。甚至会出现cpu长期高负荷、宕机等现象。在如此场景下,就不得不对数据库开刀了。这次Z哥就来和你聊聊做数据库的「伸缩性」有哪些好方法。核心诉求面临数据库需要开刀的时候,整个系统往往已经长成这个样子了。正如前面所说,这时候的瓶
Allin云+时代,数据库的高可用性、按需付费、按需扩展等属性解放了大批开发者。腾讯发布的自研数据库CynosDB作为国内首款同时兼容MySQL和PG的云原生数据库在业内引发热议,还不够了解TA?那么本期分享你一定不能错过!本期云+社区技术沙龙将全方位解读CynosDB,揭秘技术内幕,解读兼容两大主流开源数据库的一主多读架构、高可用架构及快速恢复实现、可计算智能存储和分布式存储。长按识别下方长图二维码,即可报名到现场与鹅厂技术大牛零距离交流!来不了现场的朋友,可以预约直播,在线精彩一样不错过~悄悄告诉你:预约观看直播可参与抽奖,腾讯云100元无门槛代金券(服务器和数据库可用)拼手速抢!分享内容 【议题一】CynosDB技术内幕——新一代计算引擎Cloudnative为云数据库以及传统数据库打开了崭新的发展方向,腾讯云CynosDB(MySQL)正是在此方向上衍生而来,专为云而打造CynosDB存储与计算分离的架构实现,不仅使其在产品性能、扩展性、可用性等方面有了大幅的提升,而且架构的解耦使得计算层和存储层都获得了很大的优化空间。 【议题二】可计算智能存储揭秘cynosdb采用日志即数
理论上来说,是的。但在工作实践中,那可就不一定了。写在前面的话我们经常会说,“HTTPS是安全的”或者“HTTP是不安全的”。但其实我们想表达的是,“HTTPS的内容更加难被窥探到”,“这将会让中间人攻击(MitM)变得更加困难”,或“连我外婆都可以轻易嗅探到HTTP数据”。尽管如此,HTTPS仍然有被黑的可能,而且在某些情况下,HTTP已经足够安全了。除此之外,如果我在一个支持HTTPS的常用实现(例如OpenSSL和Heartbleed)中发现了一个可以利用的漏洞,那么在漏洞被修复之前,HTTPS将会成为我入侵目标系统的垫脚石。HTTPS其实是HTTP的安全升级版(参考IETFRFC:7230、7237和2828),但我们也不能百分之百地认定HTTPS就是安全的,而HTTP就绝对不安全。在安全方面,虚拟机(VM)和容器(Container)的定义就没有那么严格了,从设计的角度来看,在这两者之间没有谁比谁更全的说法。因此,这也让它们的安全问题更加扑朔迷离了。为什么我会认为VM比Container更加安全呢?无论在战争中还是在软件开发中,“分而治之”的概念都是我们的制胜法宝。我们可以将
1.接口描述接口请求域名:teo.tencentcloudapi.com。 本接口(DescribeWebManagedRulesHitRuleDetail)用于查询WAF攻击命中规则详情。 默认接口请求频率限制:100次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DescribeWebManagedRulesHitRuleDetail。 Version 是 String 公共参数,本接口取值:2022-09-01。 Region 是 String 公共参数,详见产品支持的地域列表。 StartTime 是 TimestampISO8601 开始时间。 EndTime 是 TimestampISO8601 结束时间。 ZoneIds.N 否 Ar
论文标题:HumanActionRecognitionUsingDeepMultilevelMultimodal(M2)FusionofDepthandInertialSensors 来源/作者机构情况:ZeeshanAhmad 解决问题/主要思想贡献: 1.将单张前景图(深度图)和惯性量结合在一起。 2.使用CNN融合多种特征 成果/优点: 缺点: 反思改进/灵感: 动作识别不仅仅是基于图像的,还有使用各种传感器的。和我的研究有领域的差别 论文主要内容与关键点: 代码实现:https://github.com/zaamad/Deep-Multilevel-Multimodal-Fusion
求使隐藏层某一个神经元取到最大激活的输入问题,即 对这个函数求最值: …………………………………...(j=1,2..100)是100个方程未知量 其中f是sigmoid函数 我们知道sigmoid函数是单调递增的,那么对上式函数求最值,就是对里面的函数求最值。,是常数,所以就是求这个方程的最大值。怎么求最大值呢? 因为令和所以。也就是求的最大值。 在矩阵理论中我们有Cauchy柯西不等式:。因为,所以即。 通过柯西不等式我们发现了的上界:,并且我们知道当的时候,能够达到上界。 但是需要注意的是,我们发现这种上界跟x有关系,也就是说这个上界是不固定的,并且随着x二范数的增加而增加。所以我们求这个方程的最大值,就必须固定这个方程的上界,也就是固定x二范数。(注意x二范数固定不是说方程的未知数x就固定了,你的x里面的100个xj还是可以变化,只要二范数不变就可以) 我们假设固定x的二范数,然后求的x的值,(w是已知量),即求下面这个方程组x的值: 我们求得的x的值为(口算即可算出): 这个就是使取到最大值的的输入。 现在你可能有一个疑问,上面是假设x的二范数,可不可以是其他的值,答案是
前言:本来我是做电视应用的,但是因为公司要出手机,人员紧张,所以就抽调我去支援一下,谁叫俺是雷锋呢!我做的一个功能就是处理手机中的应用ICON,处理无非就是美化一下,重新与底板进行合成和裁剪,用到了很多Bitmap的知识。本来之前一直想写一些关于Bitmap的博客,正好这是个机会,因此Bitmap那些事系列博客诞生了。这个系列我会把学习Bitmap的一些知识发布出来供大家参考和交流。 在手机中图片一般都是指Bitmap图片,为什么要说Bitmap呢?因为大家在开发应用的时候,都会使用一些图片来表现UI,用户也喜欢看图片,看文字获取信息太慢并且不直观,如果美工设计的好,看图片基本上不怎么看你的文字内容就知道你要表达什么,例如所有的购物网站都会编辑很多商品的配图来呈现给用户,由此可见图片在应用程序中的常见和重要。只要说到图片就不能离开如何避免OOM这个主题,因为在处理很多图片时很容易出现OOM,那么学习图片处理就显得尤为重要了,下面就让我们一步一步学习图片的相关知识。 Bitmap图片占用内存计算: &nb
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。你可以不使用额外空间来实现吗?示例1:输入:[2,2,3,2]输出:3示例2:输入:[0,1,0,1,0,1,99]输出:99来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/single-number-ii著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解答: 对于上题而言,这题又变了,将相同的数字变成了3个,所以异或操作就行不通了, 这里的解法是考虑所有元素的每个bit位,因为如果在这个bit上只存在3个元素的,就是3的倍数,不然就是3的倍数+1,所以对于32个bit都这么进行处理,如果遇到3的倍数+1的,就保存这个1,不然就说明单个元素对应的二进制位在这个bit上不是1,而是0。 1classSolution{ 2publicintsingleNumber(int[]nums){ 3intres=0; 4for(inti=0;i<32;i++) 5{ 6in
经过多次折腾之后,在一次进行了一次重大的重构,去解决问题 主要重构如下 1.将原来的单一协议修改多协议进行,一些查询、认证的功能都采用HTTP进行,避免全部采用TCP链接资源的消耗; 2.原来单一的部署,划分多个分布式的系统,添加怪物自动管理系统(怪物的刷新,配置等)、后台服务系统(游戏过程中逻辑数据处理)、webAPI查询认证系统(查询和认证)、游戏后台辅助系统(主要监控其他项目的运行情况,用于容灾处理)、缓存服务器(redis)、数据服务器、资源服务器(配置文件); 现在基本解决了原来出现的问题,算一个最基础的游戏服务器设计,目前数据量在不是特别大情况都能够正常运行,如果数据量增长速度过快,就可以将系统集群分布部署基本就可以解决问题,目前还处理开发和测试阶段,这种设计的问题暂时没有发现,希望不会有下一次重大的重构、重构、重构重要事情说三遍!
BuildingApacheThriftonCentOS6.5 Startingwithaminimalinstallation,thefollowingstepsarerequiredtobuildApacheThriftonCentos6.5.Thisexamplebuildsfromsource,usingthecurrentdevelopmentmasterbranch.TheseinstructionsshouldalsoworkwithApacheThriftreleasesbeginning with0.9.2. UpdatetheSystem sudoyum-yupdate 复制 InstallthePlatformDevelopmentTools sudoyum-ygroupinstall"DevelopmentTools" 复制 Upgradeautoconf/automake/bison sudoyuminstall-ywget 复制 Upgradeautoconf wgethttp://ftp.gnu.org/gnu/autoconf/
我以前发过一个解决火狐浏览器附加组件网站速度慢的解决方法,其实今天要说的谷歌应用商店速度慢的解决办法和火狐的方法一样,就是通过修改host文件。先看看我解决后的效果吧:我昨天已经说过了怎么制作绿色的谷歌浏览器http://www.cnblogs.com/shenjieblog/p/5290106.html制作好了当然要安装一些扩展,以前我都是直接使用代理工具来安装,有点慢,不过还是可以安装,不过昨天发现就算使用代理工具都不能安装了,速度很慢,只要断开又不能断点续传,所以就百度解决方法,发现了修改host文件的方法,原贴如下:http://blog.my-eclipse.cn/host-google.html【2016更新】修改Host文件,让你的Google跑起来2016Googlehosts(2016-2-29更新hosts文件)近期,相信大家都发现了,国内Google访问狠不给力,基本上打不开,谷歌在相关的服务器也被搬到了美国,这不禁让人感慨,谷歌难道要全面退出中国的节奏?作为一名“IT界”的淫才,百度往往会让你使用的特别“蛋疼”,针对于专业领域的搜索结果更是鸡肋,针对性不强,垃圾
在android里进行邮件客户端开发可以有两种方式:在邮件客户端的设计中,可以采用两种方法。l一种是调用android系统自带的邮件服务优点:这种方法比较简单易用缺点:发送邮件的账号必须是gmail账号l令一种方法是采用javamail功能包优点:可以设置邮件服务器地址,不必局限于gmail邮箱缺点:用法比较复杂下面依次介绍这两种方式:先看应用android自带邮件系统的关键代码1.//建立Intent对象 2.Intentintent=newIntent(); 3.//设置对象动作 4.intent.setAction(Intent.ACTION_SEND); 5.//设置对方邮件地址 6.intent.putExtra(Intent.EXTRA_EMAIL,newString[] 7.{"abc@com.cn","edf@com.cn"}); 8.//设置标题内容 9.in
题目链接 https://ac.nowcoder.com/acm/contest/5670/I 题意 给你n*m的矩阵,以及三个角色:总部、金矿工和收藏家,在矩阵的每个点放置一名角色,要求总部H的旁边至少有一个金矿工G和收藏家E。问如何排布能使这种总部数量最多。 题解 菜鸡打表找规律,猛男直接推公式。 一开始以为按照GHEHGE…排布,答案是0.5。最后发现还有更加巧妙的。(说实话答案可以猜,但真不好想)大致排列方式如下,可以看出G、E都是隔一行出现,并且以斜着的形式分部。所以不难发现答案为2/3。 盲猜莽了n发过了。 #include<bits/stdc++.h> usingnamespacestd; intmain(){ doubleans; ans=2.0/3; printf("%.6lf\n",ans); return0; }复制