深度优先

这个家伙好懒,除了文章什么都没留下

0%

问题

docker容器日志导致主机磁盘空间满了。docker logs -f container_name噼里啪啦一大堆,很占用空间,不用的日志可以清理掉了。

解决方法

找出Docker容器日志

在linux上,容器日志一般存放在/var/lib/docker/containers/container_id/下面, 以json.log结尾的文件(业务日志)很大,查看各个日志文件大小的脚本docker_log_size.sh,内容如下:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

echo "======== docker containers logs file size ========"

logs=$(find /var/lib/docker/containers/ -name *-json.log)

for log in $logs
do
ls -lh $log
done

1
2
3
4
# chmod +x docker_log_size.sh

# ./docker_log_size.sh

清理Docker容器日志(治标)

如果docker容器正在运行,那么使用rm -rf方式删除日志后,通过df -h会发现磁盘空间并没有释放。原因是在Linux或者Unix系统中,通过rm -rf或者文件管理器删除文件,将会从文件系统的目录结构上解除链接(unlink)。如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。正确姿势是cat /dev/null > *-json.log,当然你也可以通过rm -rf删除后重启docker。接下来,提供一个日志清理脚本clean_docker_log.sh,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh

echo "======== start clean docker containers logs ========"

logs=$(find /var/lib/docker/containers/ -name *-json.log)

for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done

echo "======== end clean docker containers logs ========"

1
2
3
4
# chmod +x clean_docker_log.sh

# ./clean_docker_log.sh

但是,这样清理之后,随着时间的推移,容器日志会像杂草一样,卷土重来。

设置Docker容器日志大小(治本)

  • 设置一个容器服务的日志大小上限

上述方法,日志文件迟早又会涨回来。要从根本上解决问题,需要限制容器服务的日志大小上限。这个通过配置容器docker-compose的max-size选项来实现

1
2
3
4
5
6
7
8
nginx:
image: nginx:1.12.1
restart: always
logging:
driver: “json-file”
options:
max-size: “5g”

重启nginx容器之后,其日志文件的大小就被限制在5GB,再也不用担心了。

  • 全局设置

新建/etc/docker/daemon.json,若有就不用新建了。添加log-dirver和log-opts参数,样例如下:

1
2
3
4
5
6
7
8
# vim /etc/docker/daemon.json

{
"registry-mirrors": ["http://f613ce8f.m.daocloud.io"],
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"}
}

max-size=500m,意味着一个容器日志大小上限是500M,
max-file=3,意味着一个容器有三个日志,分别是id+.json、id+1.json、id+2.json。

1
2
3
4
5
6
// 重启docker守护进程

# systemctl daemon-reload

# systemctl restart docker

注意:设置的日志大小,只对新建的容器有效。

参考文章

https://blog.csdn.net/xunzhaoyao/article/details/72959917
https://www.cnblogs.com/testzcy/p/7904829.html

获取照片的人脸头像,性别,年龄,睁眼,笑容等信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Luxand;

namespace FaceDemo
{
public partial class Form1 : Form
{
private String cameraName;

// WinAPI procedure to release HBITMAP handles returned by FSDKCam.GrabFrame
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
if (FSDK.FSDKE_OK != FSDK.ActivateLibrary("***************"))
{
MessageBox.Show("Please run the License Key Wizard (Start - Luxand - FaceSDK - License Key Wizard)", "Error activating FaceSDK", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}

FSDK.InitializeLibrary();
FSDKCam.InitializeCapturing();
}

private void button3_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "JPEG (*.jpg)|*.jpg|Windows bitmap (*.bmp)|*.bmp|All files|*.*";
dlg.Multiselect = true;

if (dlg.ShowDialog() == DialogResult.OK)
{
try
{
//假设面部是垂直的(HandleArbitraryRotations = false)以加快面部检测速度
FSDK.SetFaceDetectionParameters(true, true, 384);
FSDK.SetFaceDetectionThreshold(3);

foreach (string fn in dlg.FileNames)
{
var image = new FSDK.CImage(fn);
var facePositions = image.DetectMultipleFaces();

foreach (var facePosition in facePositions)
{
var faceImage = image.CopyRect(
(int)(facePosition.xc - Math.Round(facePosition.w * 0.5)),
(int)(facePosition.yc - Math.Round(facePosition.w * 0.5)),
(int)(facePosition.xc + Math.Round(facePosition.w * 0.5)),
(int)(facePosition.yc + Math.Round(facePosition.w * 0.5)));

faceImage.Save($"{Guid.NewGuid().ToString()}.png");
}

int tracker = 0;
FSDK.CreateTracker(ref tracker);
int err = 0; // 设置实时人脸检测参数
FSDK.SetTrackerMultipleParameters(tracker, "RecognizeFaces=false;DetectExpression=true; DetectAge=true; DetectGender=true; HandleArbitraryRotations=false; DetermineFaceRotationAngle=false; InternalResizeWidth=100; FaceDetectionThreshold=5;", ref err);

long[] IDs;
long faceCount = 0;
FSDK.FeedFrame(tracker, 0, image.ImageHandle, ref faceCount, out IDs, sizeof(long) * 256); // maximum 256 faces detected
Array.Resize(ref IDs, (int)faceCount);

Image frameImage = image.ToCLRImage();
Graphics gr = Graphics.FromImage(frameImage);

for (int i = 0; i < IDs.Length; ++i)
{
FSDK.TFacePosition facePosition = new FSDK.TFacePosition();
FSDK.GetTrackerFacePosition(tracker, 0, IDs[i], ref facePosition);

int left = facePosition.xc - (int)(facePosition.w * 0.6);
int top = facePosition.yc - (int)(facePosition.w * 0.5);
int w = (int)(facePosition.w * 1.2);
gr.DrawRectangle(Pens.LightGreen, left, top, w, w);

String AttributeValues;
String AttributeValuesAge;
String AttributeValuesExpression;
if (0 == FSDK.GetTrackerFacialAttribute(tracker, 0, IDs[i], "Gender", out AttributeValues, 1024)
&& 0 == FSDK.GetTrackerFacialAttribute(tracker, 0, IDs[i], "Age", out AttributeValuesAge, 1024)
&& 0 == FSDK.GetTrackerFacialAttribute(tracker, 0, IDs[i], "Expression", out AttributeValuesExpression, 1024))
{
float ConfidenceAge = 0.0f;
float ConfidenceMale = 0.0f;
float ConfidenceSmile = 0.0f;
float ConfidenceFemale = 0.0f;
float ConfidenceEyesOpen = 0.0f;

FSDK.GetValueConfidence(AttributeValuesExpression, "Smile", ref ConfidenceSmile);
FSDK.GetValueConfidence(AttributeValuesExpression, "EyesOpen", ref ConfidenceEyesOpen);
FSDK.GetValueConfidence(AttributeValuesAge, "Age", ref ConfidenceAge);
FSDK.GetValueConfidence(AttributeValues, "Male", ref ConfidenceMale);
FSDK.GetValueConfidence(AttributeValues, "Female", ref ConfidenceFemale);

StringBuilder sb = new StringBuilder();

sb.Append($"Smile:{((int)(ConfidenceSmile * 100)).ToString()}%,");
sb.Append($"Eyes open:{((int)(ConfidenceEyesOpen * 100)).ToString()}%,");
sb.Append($"Age:{(int)ConfidenceAge},");
sb.Append($"{(ConfidenceMale > ConfidenceFemale ? "Male" : "Female")}:");
sb.Append($"{(ConfidenceMale > ConfidenceFemale ? (int)(ConfidenceMale * 100) : (int)(ConfidenceFemale * 100)).ToString()}%");

StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;

gr.DrawString(sb.ToString(), new Font("Arial", 16), new SolidBrush(Color.DarkRed), facePosition.xc, top + w + 5, format);

this.textBox1.Text = this.textBox1.Text + "\n" + sb.ToString();
}
}
pictureBox1.Image = frameImage;

GC.Collect(); // collect the garbage

// make UI controls accessible
Application.DoEvents();
FSDK.FreeTracker(tracker);

FSDKCam.FinalizeCapturing();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Exception");
}
}
}
}
}

在此Raspberry Pi TeamViewer教程中,我们将向您展示如何在Raspberry Pi上设置并连接到TeamViewer。

树莓派 TeamViewer

对于那些不知道TeamViewer是什么的人,它是专有软件,在共享桌面以及允许其他人远程访问该设备方面非常受欢迎。 支持团队大量使用它,因为它可以使诊断和解决问题变得更加容易。

我们将要安装到Raspberry Pi的TeamViewer版本称为 TeamViewer Host 。 与TeamViewer的标准版本不同,它纯粹用于接收连接并充当服务器。

您不能在Raspberry Pi上使用TeamViewer来连接到其他TeamViewer客户端,但是其他人可以连接到它。

要在Raspberry Pi上安装TeamViewer,您必须 使用 运行Raspbian Jessie或更高版本 的Raspberry Pi 2 或更高版本。

这意味着,除非您正在运行的Raspberry Pi版本已经过时,否则TeamViewer软件应适用于绝大多数人。

还有其他方法可以远程连接到Raspberry Pi,例如使用 VNC服务器 。 对于纯 终端共享, 您可以使用tmate之类的东西。

设备

以下是在Raspberry Pi上设置TeamViewer所需的所有设备。

推荐的

Raspberry Pi 2或更高版本(2、3、3B +)

8GB SD卡Micro SD卡( 如果您使用的是Raspberry Pi 2、3或B +

USB键盘

USB鼠标

HDMI线

以太网线Wifi加密狗

可选的

覆盆子皮套

将TeamViewer安装到Raspberry Pi

1. 要将TeamViewer安装到您的Raspberry Pi,我们首先必须确保我们的软件包列表和所有已安装的软件包都是最新的。

您可以通过运行以下命令来实现。

1
2
sudo apt-get update
sudo apt-get upgrade

2. 现在有了Raspberry Pi完全是最新的。 让我们继续前进,从Teamviewer的服务器下载软件包。

由于我们已经在使用命令行,因此可以通过运行以下命令来实现。 此命令将使用 wget 从TeamViewer的服务器 下载 .deb 文件。

一个 .deb文件 文件是专为Debian的系统包管理系统中的软件包文件。 该 deb包 文件是包含我们需要的TeamViewer的所有文件的存档。

1
wget https://download.teamviewer.com/download/linux/teamviewer-host_armhf.deb

3. 现在,我们在Raspberry Pi上提供了TeamViewer deb文件,让我们继续运行以下命令来安装它。

要安装TeamViewer deb软件包,我们将使用 dpkg实用程序 ,它是Debian软件包管理软件的基础。

1
sudo dpkg -i teamviewer-host_armhf.deb

4. 运行上述命令后,您会注意到一堆关于未安装特定软件包的错误。

要解决此问题,我们将必须利用我们的软件包管理器来修复“损坏的安装”。

apt软件包管理器将自动检测丢失的软件包,并尝试下载适用于该软件的最佳版本。

现在,通过运行以下命令来使用apt工具。

1
sudo apt --fix-broken install

5. TeamViewer现在应该在您的Raspberry Pi上启动并运行。 该软件是自动设置的,因此它将在启动时启动,因此您不必为此担心。

在接下来的两个部分中,我们将探索在GUI设置和无头设置上使用TeamViewer的方法。

使用TeamViewer,即使您正在运行 仅具有命令行 的 精简版Raspbian ,也可以访问Raspberry Pi 。 TeamViewer设置为也共享命令行屏幕。

在无头Raspberry Pi安装程序上使用TeamViewer

1. 在从TeamViewer客户端访问Raspberry Pi之前,我们首先必须指定服务器的密码。

我们可以通过运行以下命令来做到这一点,其中”“是您要使用的密码。

确保此密码安全,因为如果有人设法获取您的TeamViewer ID和密码,它将允许某人访问您的Raspberry Pi。

1
sudo teamviewer passwd <password>

2. 现在我们已经在Raspberry Pi上为TeamViewer设置了密码,现在我们继续获取TeamViewer ID。

TeamViewer ID是您用来与Raspberry Pi上的TeamViewer服务器建立连接的ID。

要检索TeamViewer ID,请在终端中输入以下命令。

1
teamviewer info

3. 您将从此命令得到的结果显示类似下面的内容。

我们拥有 {xxxxxxxxxx}的位置 就是您的TeamViewer ID所在的位置,请记下该数字,因为您需要使用它来连接到Raspberry Pi。

1
2
3
TeamViewer                           14.2.2558  (DEB)

TeamViewer ID: {xxxxxxxxxx}

4. 或者,如果您希望能够更轻松地通过TeamViewer连接到Raspberry Pi,则可以将设备连接到 TeamViewer帐户

要开始此过程,请运行以下命令。

1
sudo teamviewer setup

5. 在设置过程中,系统将要求您同意条款和条件,并输入TeamViewer帐户的详细信息。

输入您的帐户详细信息是为了使TeamViewer可以与其建立连接,并允许您轻松地通过TeamViewer界面访问您的帐户。

完成设置过程后,您现在应该可以连接到Raspberry Pi上运行的TeamViewer服务器。

您可以跳到”使用TeamViewer连接到Raspberry Pi” 部分,以了解如何连接到Raspberry Pi的TeamViewer安装。

在Raspberry Pi上的GUI中使用TeamViewer

1. 将TeamViewer安装到Raspberry Pi上后,将出现以下屏幕,要求您接受TeamViewer的许可协议。

要继续阅读本指南,您需要单击”接受许可协议” 按钮。

TeamViewer许可协议

2. 同意许可协议后,您将返回桌面。

要打开Teamviewer主机软件,请单击 任务栏中 的 TeamViewer 图标,如下面的屏幕快照所示。

TeamViewer图标桌面

3. 在此屏幕中,您需要确定是要将Raspberry Pi与TeamViewer帐户关联,还是要设置密码并使用TeamViewer ID进行连接。

如果要依靠使用TeamViewer ID,请继续并单击”设置个人密码”。1. )加载选项菜单。 如果选择此选项,请确保跳至 本教程的 第5步

如果您决定使用TeamViewer帐户连接到Raspberry Pi,请继续并单击”授予轻松访问2 )”按钮。 如果选择此选项,请继续执行 本教程的 第4步

TeamViewer应用选择访问或设置密码

4. 如果您决定将Raspberry Pi的TeamViewer主机连接到TeamViewer帐户,现在将要求您”分配您的帐户“。

此过程会将您的设备连接到TeamViewer帐户,从而轻松访问。 您需要做的就是输入您的 电子邮件 以及 密码1. )。

输入所有信息后,需要单击”分配” 按钮( 2. )。 单击按钮将完成连接并关联设备。

现在,您可以继续 本Raspberry Pi Teamviewer教程的 第6步

TeamViewer分配给帐户

5. 如果您决定依赖使用TeamViewer ID,则需要设置密码。

点击“后, 设置个人密码。“,在 第3步中 ,您将看到TeamViewer选项菜单。

在此菜单中,单击”安全性“选项卡,如下面的屏幕快照所示。

TeamViewer选项

6. 在此屏幕上,在”个人密码1. )”部分 下设置密码 。 确保您保持此安全,因为如果有人获得了它以及您的TeamViewer ID,则可以获取访问权限。

设置密码后,按”应用” 按钮。

TeamViewer选项设置密码

7. 设置TeamViewer个人访问密码后,默认的TeamViewer界面现在应该会打招呼,如下所示。

在这里,将显示您的TeamViewer ID,使用该ID和密码,您将能够利用TeamViewer软件连接到Raspberry Pi。

TeamViewer检索ID

使用TeamViewer连接到Raspberry Pi

1. 现在在您的Raspberry Pi上设置了TeamViewer之后,我们现在可以开始连接它了。

要连接到它,您将需要一台装有TeamViewer客户端的设备,无论它是Windows PC还是大多数其他设备。

您可以通过 访问TeamViewer网站 下载TeamViewer 。 安装完成后,继续下一步。

2. 现在,在装入TeamViewer的情况下,您将可以输入TeamViewer ID( 2. )并以这种方式连接到Raspberry Pi。

或者,如果您将Raspberry Pi连接到TeamViewer帐户,则可以在连接列表中双击它以连接到设备。

TeamViewer Desktop Select Raspberry Pi

3. 使用TeamViewer连接到Raspberry Pi后,桌面或命令行都会给您打招呼,具体取决于您所使用的Raspbian版本。

如果一切都正确连接,那么您现在已经成功在Raspberry Pi上设置了TeamViewer。

TeamViewer已连接

现在,您应该使一切正常。 如果您对此Raspberry Pi Teamviewer教程有任何反馈,请不要在下面发表评论。