laravel5日志设置篇(3/3) – 精确到微秒及日志输出位置记录

想要实现的功能

  • 记录日志输出时的时间精度到微秒
  • 记录日志输出时程序执行位置(方法/行数)
  • 记录进程ID

例如:

  • app.log
[2017-10-22 10:13:57.833504] production.INFO: -- Startup {"method":"GET","uri":"/v1/stocks"} {"pid":7124,"line":"App\\Bootstrap\\ApplicationLog->startupLog:66"}
[2017-10-22 10:13:57.898702] production.INFO: get stocks info  {"pid":7124,"line":"App\\Http\\Controllers\\StocksController->index:66"}
[2017-10-22 10:13:57.903274] production.INFO: -- Shutdown {"time":"70.371[ms]","memory":"2048[kb]"} {"pid":7124,"line":"App\\Bootstrap\\ApplicationLog->handleShutdownLog:81"}

Continue reading →

laravel5日志设置篇(2/3) – 记录sql日志

想要实现的功能

  • 获取laravel运行时执行的sql语句
  • sql相关的日志保存到指定文件(sql.log)
  • 接口访问与artisan 命令日志分开保存

例如

  • sql.log
[2017-10-21 22:27:42] production.DEBUG: select count(*) as aggregate from `stocks_input` where `stocks_input`.`deleted_at` is null; {"time":0.55} 
[2017-10-21 22:27:42] production.DEBUG: select * from `stocks_input` where `stocks_input`.`deleted_at` is null order by `created_at` desc limit 10 offset 0; {"time":0.84} 
[2017-10-21 22:27:42] production.DEBUG: select * from `goods` where `goods`.`id` = 1 limit 1; {"time":0.74} 
  • cli.sql.log
[2017-10-21 22:28:15] production.DEBUG: select * from `goods` where `goods`.`id` = 1 limit 1; {"time":0.76} 
[2017-10-21 22:28:15] production.DEBUG: select * from `regions` where `regions`.`id` = 110102 limit 1; {"time":0.87} 
[2017-10-21 22:28:15] production.DEBUG: select * from `regions` where `regions`.`id` = 110000 limit 1; {"time":0.81} 

Continue reading →

laravel5日志设置篇(1/3) – 记录开始和结束日志

想要实现的功能

记录Application的开始和结束日志
– 开始日志: URL请求或命令行记录
– 结束日志: 处理时间和内存使用峰值记录

例如:

[2017-10-19 23:06:00] local.INFO: -- Startup {"command":"php artisan list"} 
[2017-10-19 23:06:00] local.INFO: -- Shutdown {"time":"36.955[ms]","memory":"10[mb]"} 
[2017-10-19 23:11:37] local.INFO: -- Startup {"method":"GET","uri":"/v1/stocks"} 
[2017-10-19 23:11:37] local.INFO: -- Shutdown {"time":"21.765[ms]","memory":"4096[kb]"} 

Continue reading →

java stream api介绍

简介

Stream API借助前面介绍的java lambda表达式来进行集合数据处理。
下面举些常用的例子来熟悉下。

forEach

stream方法不调用也可以使用forEach

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).forEach(System.out::println);

filter

集合内数据过滤

Arrays.asList(new Double[] { 1.0, 2.1, 3.2, 4.3, 5.4 }).stream().filter(x -> x > 3.0).forEach(System.out::println);

Continue reading →

判断是不是iphone x齐刘海屏幕

判断规则

由于iphone x屏幕不是传统的长方形了,而是圆角矩形。如何判断当前的屏幕是长方形还是圆角矩形呢?
可以使用windows的safeAreaInsets方法,当返回值为0时,为长方形,非0时即认为是iphone x.

func isiPhoneXScreen() -> Bool {
        guard #available(iOS 11.0, *) else {
            return false
        }

        return UIApplication.shared.windows[0].safeAreaInsets != UIEdgeInsets.zero
}

Continue reading →

Java lambda表达式

lambda表达式

lambda表达式是一种只拥有一个函数式接口的方法的叫法,可以简化封装。

函数式接口

在lisp这样的函数式编辑语言中,可以简单地把函数当作参数传递。在java中,由于函数不是对象,故不能直接当作参数传递。但可以通过函数式接口实现函数传递。

package foo;

public interface Func {
    public double apply(double x);
}

ps. 函数式接口只拥有一个抽象方法的接口
Continue reading →

从问题角度来思考设计模式(2) – 结构编

目录

  1. 生成编
  2. 结构编
  3. 行为编

让API返回信息适配多样性

  • 改造前
FooAPI fooAPI = new FooAPI(lat, lng);
FooPlace place = new FooPlace();
place.setAddress(fooAPI.getPostalCode() + " " + fooAPI.getAddress()); // 邮编 **市**区
place.setStation(
    new StringJoiner(",")
    .add(fooAPI.getStation1())
    .add(fooAPI.getStation2())
    .add(fooAPI.getStation3())
    .toString());  //A车站,B车站,C车站

上面代码是API返回信息整形用例。这里只使用了FooAPI,未来如果返回信息的整形方式不变的话,倒也没有什么问题。但从易维护的角度思考,这称不上一个好的设计。
Continue reading →

从问题角度来思考设计模式(1) – 生成编

目录

  1. 生成编
  2. 结构编
  3. 行为编

简介

关于设计模式可以理解为,那些经常会遇到的问题以及如何解决所洗练出来的总结。所以我们在考虑进行设计时,首先要做的就是查询当前所面临的问题,是否已经有很好的解决方案,而不是闭门造车。身边有些同事喜欢需求来了,直接上来就撸代码,认为为了迎合设计模式而设计的工作,会有过度设计的嫌疑。什么时候是导入新工具,新技术的最佳时机?当一个事物让人难以忍受的时候,这时改变所带来的团队收益远大于痛苦程度,就可以很平缓地推进。反之,强推工具反而引来的不是技术上的问题,而是人为的抵制。是不是很奇妙!

本文主要通过问题配合设计模式,来说明设计模式所带来的前后效果,加深大家各种模式的印象。

Continue reading →